├── EEX6563 (java interface)
├── build.xml
├── build
│ ├── built-jar.properties
│ └── classes
│ │ ├── .netbeans_automatic_build
│ │ ├── .netbeans_update_resources
│ │ └── eex6563
│ │ ├── EEX6563$1.class
│ │ ├── EEX6563$2.class
│ │ ├── EEX6563$3.class
│ │ ├── EEX6563.class
│ │ └── EEX6563.form
├── calc
├── compile.sh
├── dist
│ ├── EEX6563.jar
│ └── README.TXT
├── manifest.mf
├── nbproject
│ ├── build-impl.xml
│ ├── genfiles.properties
│ ├── private
│ │ ├── private.properties
│ │ └── private.xml
│ ├── project.properties
│ └── project.xml
├── output.js
└── src
│ └── eex6563
│ ├── EEX6563.form
│ └── EEX6563.java
├── EEX6563 Mini Project Report for git.pdf
├── Makefile
├── Makefile copy
├── README.md
├── calc
├── calc.c
├── calc.h
├── calc.l
├── calc.y
├── calc3b.c
├── compile.sh
├── images
├── 1.png
├── 2.png
├── 3.png
├── derivation.png
├── grammar.png
├── ndfa.png
├── test1.png
├── test2.png
└── test3.png
├── lex.yy.c
├── y.tab.c
└── y.tab.h
/EEX6563 (java interface)/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Builds, tests, and runs the project EEX6563.
12 |
13 |
73 |
74 |
--------------------------------------------------------------------------------
/EEX6563 (java interface)/build/built-jar.properties:
--------------------------------------------------------------------------------
1 | #Sun, 31 May 2020 22:56:18 +0530
2 |
3 |
4 | /Volumes/Documents/OUSL/EEX6563\ Software\ Construction/TMA\ 2/test/New\ Folder\ With\ Items/TMA\ 3/EEX6563=
5 |
--------------------------------------------------------------------------------
/EEX6563 (java interface)/build/classes/.netbeans_automatic_build:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandunrajitha/Compiler-Design-and-Implementation-using-lex-and-yacc/6d2089452d02de8977a7a820b64ae4e3d8c93729/EEX6563 (java interface)/build/classes/.netbeans_automatic_build
--------------------------------------------------------------------------------
/EEX6563 (java interface)/build/classes/.netbeans_update_resources:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandunrajitha/Compiler-Design-and-Implementation-using-lex-and-yacc/6d2089452d02de8977a7a820b64ae4e3d8c93729/EEX6563 (java interface)/build/classes/.netbeans_update_resources
--------------------------------------------------------------------------------
/EEX6563 (java interface)/build/classes/eex6563/EEX6563$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandunrajitha/Compiler-Design-and-Implementation-using-lex-and-yacc/6d2089452d02de8977a7a820b64ae4e3d8c93729/EEX6563 (java interface)/build/classes/eex6563/EEX6563$1.class
--------------------------------------------------------------------------------
/EEX6563 (java interface)/build/classes/eex6563/EEX6563$2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandunrajitha/Compiler-Design-and-Implementation-using-lex-and-yacc/6d2089452d02de8977a7a820b64ae4e3d8c93729/EEX6563 (java interface)/build/classes/eex6563/EEX6563$2.class
--------------------------------------------------------------------------------
/EEX6563 (java interface)/build/classes/eex6563/EEX6563$3.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandunrajitha/Compiler-Design-and-Implementation-using-lex-and-yacc/6d2089452d02de8977a7a820b64ae4e3d8c93729/EEX6563 (java interface)/build/classes/eex6563/EEX6563$3.class
--------------------------------------------------------------------------------
/EEX6563 (java interface)/build/classes/eex6563/EEX6563.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandunrajitha/Compiler-Design-and-Implementation-using-lex-and-yacc/6d2089452d02de8977a7a820b64ae4e3d8c93729/EEX6563 (java interface)/build/classes/eex6563/EEX6563.class
--------------------------------------------------------------------------------
/EEX6563 (java interface)/build/classes/eex6563/EEX6563.form:
--------------------------------------------------------------------------------
1 |
2 |
3 |
134 |
--------------------------------------------------------------------------------
/EEX6563 (java interface)/calc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandunrajitha/Compiler-Design-and-Implementation-using-lex-and-yacc/6d2089452d02de8977a7a820b64ae4e3d8c93729/EEX6563 (java interface)/calc
--------------------------------------------------------------------------------
/EEX6563 (java interface)/compile.sh:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | SOURCE=$1
3 | echo $SOURCE | ./calc
4 |
--------------------------------------------------------------------------------
/EEX6563 (java interface)/dist/EEX6563.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandunrajitha/Compiler-Design-and-Implementation-using-lex-and-yacc/6d2089452d02de8977a7a820b64ae4e3d8c93729/EEX6563 (java interface)/dist/EEX6563.jar
--------------------------------------------------------------------------------
/EEX6563 (java interface)/dist/README.TXT:
--------------------------------------------------------------------------------
1 | ========================
2 | BUILD OUTPUT DESCRIPTION
3 | ========================
4 |
5 | When you build an Java application project that has a main class, the IDE
6 | automatically copies all of the JAR
7 | files on the projects classpath to your projects dist/lib folder. The IDE
8 | also adds each of the JAR files to the Class-Path element in the application
9 | JAR files manifest file (MANIFEST.MF).
10 |
11 | To run the project from the command line, go to the dist folder and
12 | type the following:
13 |
14 | java -jar "EEX6563.jar"
15 |
16 | To distribute this project, zip up the dist folder (including the lib folder)
17 | and distribute the ZIP file.
18 |
19 | Notes:
20 |
21 | * If two JAR files on the project classpath have the same name, only the first
22 | JAR file is copied to the lib folder.
23 | * Only JAR files are copied to the lib folder.
24 | If the classpath contains other types of files or folders, these files (folders)
25 | are not copied.
26 | * If a library on the projects classpath also has a Class-Path element
27 | specified in the manifest,the content of the Class-Path element has to be on
28 | the projects runtime path.
29 | * To set a main class in a standard Java project, right-click the project node
30 | in the Projects window and choose Properties. Then click Run and enter the
31 | class name in the Main Class field. Alternatively, you can manually type the
32 | class name in the manifest Main-Class element.
33 |
--------------------------------------------------------------------------------
/EEX6563 (java interface)/manifest.mf:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | X-COMMENT: Main-Class will be added automatically by build
3 |
4 |
--------------------------------------------------------------------------------
/EEX6563 (java interface)/nbproject/genfiles.properties:
--------------------------------------------------------------------------------
1 | build.xml.data.CRC32=a9912f6e
2 | build.xml.script.CRC32=43939446
3 | build.xml.stylesheet.CRC32=f85dc8f2@1.94.0.48
4 | # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
5 | # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
6 | nbproject/build-impl.xml.data.CRC32=a9912f6e
7 | nbproject/build-impl.xml.script.CRC32=567bdd07
8 | nbproject/build-impl.xml.stylesheet.CRC32=f89f7d21@1.94.0.48
9 |
--------------------------------------------------------------------------------
/EEX6563 (java interface)/nbproject/private/private.properties:
--------------------------------------------------------------------------------
1 | compile.on.save=true
2 | user.properties.file=/Users/sandunliyanage/Library/Application Support/NetBeans/12.1/build.properties
3 |
--------------------------------------------------------------------------------
/EEX6563 (java interface)/nbproject/private/private.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/EEX6563 (java interface)/nbproject/project.properties:
--------------------------------------------------------------------------------
1 | annotation.processing.enabled=true
2 | annotation.processing.enabled.in.editor=false
3 | annotation.processing.processor.options=
4 | annotation.processing.processors.list=
5 | annotation.processing.run.all.processors=true
6 | annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
7 | build.classes.dir=${build.dir}/classes
8 | build.classes.excludes=**/*.java,**/*.form
9 | # This directory is removed when the project is cleaned:
10 | build.dir=build
11 | build.generated.dir=${build.dir}/generated
12 | build.generated.sources.dir=${build.dir}/generated-sources
13 | # Only compile against the classpath explicitly listed here:
14 | build.sysclasspath=ignore
15 | build.test.classes.dir=${build.dir}/test/classes
16 | build.test.results.dir=${build.dir}/test/results
17 | # Uncomment to specify the preferred debugger connection transport:
18 | #debug.transport=dt_socket
19 | debug.classpath=\
20 | ${run.classpath}
21 | debug.modulepath=\
22 | ${run.modulepath}
23 | debug.test.classpath=\
24 | ${run.test.classpath}
25 | debug.test.modulepath=\
26 | ${run.test.modulepath}
27 | # Files in build.classes.dir which should be excluded from distribution jar
28 | dist.archive.excludes=
29 | # This directory is removed when the project is cleaned:
30 | dist.dir=dist
31 | dist.jar=${dist.dir}/EEX6563.jar
32 | dist.javadoc.dir=${dist.dir}/javadoc
33 | dist.jlink.dir=${dist.dir}/jlink
34 | dist.jlink.output=${dist.jlink.dir}/EEX6563
35 | excludes=
36 | includes=**
37 | jar.compress=false
38 | javac.classpath=
39 | # Space-separated list of extra javac options
40 | javac.compilerargs=
41 | javac.deprecation=false
42 | javac.external.vm=true
43 | javac.modulepath=
44 | javac.processormodulepath=
45 | javac.processorpath=\
46 | ${javac.classpath}
47 | javac.source=1.8
48 | javac.target=1.8
49 | javac.test.classpath=\
50 | ${javac.classpath}:\
51 | ${build.classes.dir}
52 | javac.test.modulepath=\
53 | ${javac.modulepath}
54 | javac.test.processorpath=\
55 | ${javac.test.classpath}
56 | javadoc.additionalparam=
57 | javadoc.author=false
58 | javadoc.encoding=${source.encoding}
59 | javadoc.html5=false
60 | javadoc.noindex=false
61 | javadoc.nonavbar=false
62 | javadoc.notree=false
63 | javadoc.private=false
64 | javadoc.splitindex=true
65 | javadoc.use=true
66 | javadoc.version=false
67 | javadoc.windowtitle=
68 | # The jlink additional root modules to resolve
69 | jlink.additionalmodules=
70 | # The jlink additional command line parameters
71 | jlink.additionalparam=
72 | jlink.launcher=true
73 | jlink.launcher.name=EEX6563
74 | main.class=eex6563.EEX6563
75 | manifest.file=manifest.mf
76 | meta.inf.dir=${src.dir}/META-INF
77 | mkdist.disabled=false
78 | platform.active=default_platform
79 | run.classpath=\
80 | ${javac.classpath}:\
81 | ${build.classes.dir}
82 | # Space-separated list of JVM arguments used when running the project.
83 | # You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
84 | # To set system properties for unit tests define test-sys-prop.name=value:
85 | run.jvmargs=
86 | run.modulepath=\
87 | ${javac.modulepath}
88 | run.test.classpath=\
89 | ${javac.test.classpath}:\
90 | ${build.test.classes.dir}
91 | run.test.modulepath=\
92 | ${javac.test.modulepath}
93 | source.encoding=UTF-8
94 | src.dir=src
95 | test.src.dir=test
96 |
--------------------------------------------------------------------------------
/EEX6563 (java interface)/nbproject/project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | org.netbeans.modules.java.j2seproject
4 |
5 |
6 | EEX6563
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/EEX6563 (java interface)/output.js:
--------------------------------------------------------------------------------
1 | var a = 5
2 | var b = 3
3 |
4 | if (a > b) {var y = 5 } else { var y = 2 }
5 |
6 | console.log( y )
7 |
--------------------------------------------------------------------------------
/EEX6563 (java interface)/src/eex6563/EEX6563.form:
--------------------------------------------------------------------------------
1 |
2 |
3 |
134 |
--------------------------------------------------------------------------------
/EEX6563 (java interface)/src/eex6563/EEX6563.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 | package eex6563;
7 |
8 | import java.io.BufferedReader;
9 | import java.io.IOException;
10 | import java.io.InputStreamReader;
11 | import java.nio.file.Files;
12 | import java.nio.file.Paths;
13 | import java.util.logging.Level;
14 | import java.util.logging.Logger;
15 |
16 | /**
17 | *
18 | * @author Sandun Rajitha
19 | */
20 | public class EEX6563 extends javax.swing.JFrame {
21 |
22 | /**
23 | * Creates new form EEX6563
24 | */
25 | String code;
26 |
27 | public EEX6563() {
28 | initComponents();
29 | }
30 |
31 | /**
32 | * This method is called from within the constructor to initialize the form.
33 | * WARNING: Do NOT modify this code. The content of this method is always
34 | * regenerated by the Form Editor.
35 | */
36 | @SuppressWarnings("unchecked")
37 | // //GEN-BEGIN:initComponents
38 | private void initComponents() {
39 |
40 | jScrollPane1 = new javax.swing.JScrollPane();
41 | codeText = new javax.swing.JTextArea();
42 | jScrollPane2 = new javax.swing.JScrollPane();
43 | outputText = new javax.swing.JTextArea();
44 | compileBtn = new javax.swing.JButton();
45 | saveBtn = new javax.swing.JButton();
46 | jLabel1 = new javax.swing.JLabel();
47 | jLabel2 = new javax.swing.JLabel();
48 |
49 | setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
50 |
51 | codeText.setColumns(20);
52 | codeText.setRows(5);
53 | jScrollPane1.setViewportView(codeText);
54 |
55 | outputText.setColumns(20);
56 | outputText.setRows(5);
57 | jScrollPane2.setViewportView(outputText);
58 |
59 | compileBtn.setText("Compile");
60 | compileBtn.addActionListener(new java.awt.event.ActionListener() {
61 | public void actionPerformed(java.awt.event.ActionEvent evt) {
62 | compileBtnActionPerformed(evt);
63 | }
64 | });
65 |
66 | saveBtn.setText("Save");
67 | saveBtn.addActionListener(new java.awt.event.ActionListener() {
68 | public void actionPerformed(java.awt.event.ActionEvent evt) {
69 | saveBtnActionPerformed(evt);
70 | }
71 | });
72 |
73 | jLabel1.setFont(new java.awt.Font("Lucida Grande", 0, 17)); // NOI18N
74 | jLabel1.setText("Code:");
75 |
76 | jLabel2.setFont(new java.awt.Font("Lucida Grande", 0, 17)); // NOI18N
77 | jLabel2.setText("Output:");
78 |
79 | javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
80 | getContentPane().setLayout(layout);
81 | layout.setHorizontalGroup(
82 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
83 | .addGroup(layout.createSequentialGroup()
84 | .addContainerGap()
85 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
86 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
87 | .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 407, javax.swing.GroupLayout.PREFERRED_SIZE)
88 | .addComponent(compileBtn, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE))
89 | .addComponent(jLabel1))
90 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
91 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
92 | .addComponent(jLabel2)
93 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
94 | .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 407, javax.swing.GroupLayout.PREFERRED_SIZE)
95 | .addComponent(saveBtn, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)))
96 | .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
97 | );
98 | layout.setVerticalGroup(
99 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
100 | .addGroup(layout.createSequentialGroup()
101 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
102 | .addComponent(jLabel1)
103 | .addComponent(jLabel2))
104 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
105 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
106 | .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 539, Short.MAX_VALUE)
107 | .addComponent(jScrollPane1))
108 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
109 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
110 | .addComponent(compileBtn, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
111 | .addComponent(saveBtn, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE))
112 | .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
113 | );
114 |
115 | pack();
116 | }// //GEN-END:initComponents
117 |
118 | private void compileBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_compileBtnActionPerformed
119 | code = codeText.getText();
120 | System.out.println(code);
121 | try {
122 | runCompiler(code);
123 | } catch (IOException ex) {
124 | Logger.getLogger(EEX6563.class.getName()).log(Level.SEVERE, null, ex);
125 | }
126 | }//GEN-LAST:event_compileBtnActionPerformed
127 |
128 | private void saveBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveBtnActionPerformed
129 | try {
130 | String content = outputText.getText();
131 | String path = "./output.js";
132 | Files.write(Paths.get(path), content.getBytes());
133 | } catch (IOException ex) {
134 | Logger.getLogger(EEX6563.class.getName()).log(Level.SEVERE, null, ex);
135 | }
136 | }//GEN-LAST:event_saveBtnActionPerformed
137 |
138 | /**
139 | * @param args the command line arguments
140 | */
141 | public static void main(String args[]) {
142 | /* Set the Nimbus look and feel */
143 | //
144 | /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
145 | * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
146 | */
147 | try {
148 | for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
149 | if ("Nimbus".equals(info.getName())) {
150 | javax.swing.UIManager.setLookAndFeel(info.getClassName());
151 | break;
152 | }
153 | }
154 | } catch (ClassNotFoundException ex) {
155 | java.util.logging.Logger.getLogger(EEX6563.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
156 | } catch (InstantiationException ex) {
157 | java.util.logging.Logger.getLogger(EEX6563.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
158 | } catch (IllegalAccessException ex) {
159 | java.util.logging.Logger.getLogger(EEX6563.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
160 | } catch (javax.swing.UnsupportedLookAndFeelException ex) {
161 | java.util.logging.Logger.getLogger(EEX6563.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
162 | }
163 | //
164 |
165 | /* Create and display the form */
166 | java.awt.EventQueue.invokeLater(new Runnable() {
167 | public void run() {
168 | new EEX6563().setVisible(true);
169 | }
170 | });
171 | }
172 |
173 |
174 | // Variables declaration - do not modify//GEN-BEGIN:variables
175 | private javax.swing.JTextArea codeText;
176 | private javax.swing.JButton compileBtn;
177 | private javax.swing.JLabel jLabel1;
178 | private javax.swing.JLabel jLabel2;
179 | private javax.swing.JScrollPane jScrollPane1;
180 | private javax.swing.JScrollPane jScrollPane2;
181 | private javax.swing.JTextArea outputText;
182 | private javax.swing.JButton saveBtn;
183 | // End of variables declaration//GEN-END:variables
184 |
185 | private void runCompiler(String code) throws IOException{
186 |
187 | try {
188 | //String[] args = new String[] {"echo", "if 4<5 then y:=5; else y:=6;", "| ./calc"};
189 | String[] args = new String[] {"./compile.sh", code};
190 | //processBuilder.command("./compile.sh", "if 4<5 then y:=5; else y:=6;");
191 | Process process = new ProcessBuilder(args).start();
192 |
193 |
194 | StringBuilder output = new StringBuilder();
195 |
196 | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
197 |
198 | String line;
199 | while ((line = reader.readLine()) != null) {
200 | output.append(line + "\n");
201 | }
202 |
203 | int exitVal = process.waitFor();
204 | if (exitVal == 0) {
205 | System.out.println(output);
206 | outputText.setText(output + "");
207 | //System.exit(0);
208 | }
209 | } catch (InterruptedException ex) {
210 | Logger.getLogger(EEX6563.class.getName()).log(Level.SEVERE, null, ex);
211 | }
212 | }
213 | }
214 |
--------------------------------------------------------------------------------
/EEX6563 Mini Project Report for git.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandunrajitha/Compiler-Design-and-Implementation-using-lex-and-yacc/6d2089452d02de8977a7a820b64ae4e3d8c93729/EEX6563 Mini Project Report for git.pdf
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | all: calc
2 |
3 | calc.tab.c calc.tab.h: calc.y
4 | bison -y -d calc.y
5 |
6 | lex.yy.c: calc.l calc.tab.h
7 | flex calc.l
8 |
9 | calc: lex.yy.c y.tab.c y.tab.h
10 | gcc -o calc y.tab.c lex.yy.c calc3b.c
11 |
12 | clean:
13 | rm calc calc.tab.c lex.yy.c calc.tab.h
14 |
--------------------------------------------------------------------------------
/Makefile copy:
--------------------------------------------------------------------------------
1 | all: calc
2 |
3 | calc.tab.c calc.tab.h: calc.y
4 | bison -y -d calc.y
5 |
6 | lex.yy.c: calc.l calc.tab.h
7 | flex calc.l
8 |
9 | calc: lex.yy.c y.tab.c y.tab.h
10 | gcc -o calc y.tab.c lex.yy.c calc.c
11 |
12 | clean:
13 | rm calc calc.tab.c lex.yy.c calc.tab.h
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # **Compiler – Design and Implementation using lex and yacc**
2 |
3 | > Created as a mini project for "Software Construction" course @ Open University of Sri Lanka
4 |
5 | ## **Introduction**
6 |
7 | ### **What is a compiler**
8 |
9 | A compiler is a program or set of programs that converts a source code written in a high level language to pure machine code, Augmented machine code or virtual machine code.
10 |
11 | ### **Compiler phases**
12 |
13 | Compiler operates in various phases; each phase transforms the source program from one representation to another. Every phase takes inputs from its previous stage and feeds its output to the next phase of the compiler.
14 |
15 | There are 6 phases in a compiler. Each of these phases help in converting the high-level language to machine code. The phases of a compiler are:
16 |
17 | - Lexical analyzer
18 | - Syntax analyzer
19 | - Semantic analyzer
20 | - Intermediate Code Generator
21 | - Code optimizer
22 | - Target code generator
23 |
24 | 
25 |
26 | **Lexical analyzer:**
27 | Reads the source code and converts it to tokens. Tokens are defined by regular expressions. Which are understood by the lexical analyzer. And the analyzer also removes the comments in the code and whitespaces.
28 |
29 | **Syntax analyzer:**
30 | This is also known as the parser. It reads the tokens one by one and uses context free grammar to construct the parse tree.
31 |
32 | **Semantic analyzer:**
33 | Verifies the parse tree, and does - type checking, Label checking and Flow control checking.
34 |
35 | **Intermediate Code Generator:**
36 | Generates intermediate code which can be executed by the machine. Till the intermediate code it's the same for every compiler. But Intermediate code generator and steps after that depends on the platform the code is compiled for.
37 |
38 | **Code optimizer:**
39 | Transforms the intermediate code in a manner that it uses fewer resources and runs faster. But the meaning of the code is not altered. And there are two types of optimization, machine dependent and machine independent.
40 |
41 | **Target code generator:**
42 | This is the final step of the compilation process. It rewrites the optimized code into machine language.
43 |
44 |
45 | **What is the Symbol table?**
46 | Symbol table is a data structure maintained and being used by the compiler which contains all the identifier names with their symbols. It helps the compiler to find the identifiers quickly.
47 |
48 | # **Design**
49 |
50 | ## **Architecture**
51 |
52 | The language supports **control structures** and **variable declarations**. And it supports **integer** , **boolean** variable types. Boolen expressions only appear in control structures. The language supports arithmetic operations **(addition, subtraction, multiplication, division)** on integers and has IF-THEN-ELSE, IF-THEN
and WHILE-DO
control structures.
53 |
54 | 
55 |
56 | ## **User Interface design**
57 |
58 | 
59 |
60 | # **Implementation**
61 |
62 | ## **Grammar**
63 |
64 |
65 | ```
66 | G = { N , T , P , S }
67 |
68 | N = { prgmbody, stmntlist, stmnt, explist, expitem, boolreln }
69 |
70 | T = { PRINT, IF,THEN, ELSE, WHILE, DO, AND, OR, PLUS, MINUS, MULTI, OVER, SEMI,
71 | LESS, BIGGER, EQUAL, LAPREN, RPAREN, ASSIGN, LESSEQ, BIGEQ }
72 |
73 | S = { prgmbody }
74 |
75 | P = {
76 | prgmbody → stmntlist
77 |
78 | stmntlist → stmnt-list stmnt
79 |
80 | stmnt → START explist END
81 | | PRINT expitem SEMI
82 | | WHILE expitem DO stmnt
83 | | IF expitem THEN stmnt
84 | | IF expitem THEN stmnt ELSE stmnt
85 | | VARIABLE ASSIGN expitem SEMI
86 |
87 | explist → expitem
88 | | explist SEMI expitem
89 |
90 | expitem → NUMBER
91 | | expitem PLUS expitem
92 | | expitem MINUS expitem
93 | | expitem MULTI expitem
94 | | expitem OVER expitem
95 | | FALSE
96 | | TRUE
97 | | VARIABLE
98 | | boolreln
99 | | LAPREN expitem RPAREN
100 | | expitem OR expitem
101 | | expitem AND expitem
102 | | NOT expitem
103 |
104 | boolreln → expitem LESS expitem
105 | | expitem LESSEQ expitem
106 | | expitem EQUAL expitem
107 | | expitem BIGEQ expitem
108 | | expitem BIGGER expitem
109 |
110 | }
111 | ```
112 | ## **NDFA and DFA**
113 |
114 | When we consider the sample statement
115 |
116 |
117 | **IF** (bool-exp)* **THEN** (stmnt)+ **ELSE** (stmnt)+;
118 |
119 |
120 | 
121 |
122 |
123 | ## **Derivation tree**
124 |
125 | Sample code:
126 |
127 | **if** 4 < 5 **then** y:=5; **else** y:=6;
128 |
129 |
130 | 
131 |
132 |
133 |
134 | ## **Lexical Analyser**
135 |
136 | ```Yacc
137 |
138 | %{
139 | #include
140 | #include "calc.h"
141 | #include "y.tab.h"
142 | void yyerror(char *);
143 | %}
144 |
145 | %%
146 |
147 | [a-z,A-Z] {yylval.sIndex = *yytext - 'a'; return VARIABLE;};
148 | "print" return PRINT;
149 | "begin" return START;
150 | "if" return IF;
151 | "then" return THEN;
152 | "else" return ELSE;
153 | "while" return WHILE;
154 | "do" return DO;
155 | "and" return AND;
156 | "or" return OR;
157 | "true" {yylval.bValue = 1; return TRUE;};
158 | "false" {yylval.bValue = 0; return FALSE;};
159 | [1-9][0-9]* {yylval.iValue = atoi(yytext); return NUMBER;};
160 | "+" return PLUS;
161 | "-" return MINUS;
162 | "*" return MULTI;
163 | "/" return OVER;
164 | ";" return SEMI;
165 | "<" return LESS;
166 | ">" return BIGGER;
167 | "=" return EQUAL;
168 | "(" return LAPREN;
169 | ")" return RPAREN;
170 | ":=" return ASSIGN;
171 | "<=" return LESSEQ;
172 | ">=" return BIGEQ;
173 | [ \t\n]+;
174 | .
175 |
176 | %%
177 |
178 | int yywrap(void) {
179 | return 1;
180 | }
181 |
182 |
183 | ```
184 |
185 |
186 | ## **Syntax Analyser**
187 |
188 | ```Yacc
189 |
190 | %{
191 | #include
192 | #include
193 | #include
194 | #include "calc.h"
195 |
196 | /* prototypes */
197 | nodeType *opr(int oper, int nops, ...);
198 | nodeType *id(int i);
199 | nodeType *con(int value);
200 | nodeType *boole(int value);
201 | void freeNode(nodeType *p);
202 | int ex(nodeType *p);
203 | int yylex(void);
204 |
205 | void yyerror(char *s);
206 | int sym[26];
207 |
208 | %}
209 |
210 | %union {
211 | int iValue; /* integer value */
212 | int bValue; /* boolean value */
213 | char sIndex; /* symbol table index */
214 | nodeType *nPtr; /* node pointer */
215 | };
216 |
217 | %token NUMBER
218 | %token TRUE FALSE
219 | %token VARIABLE
220 | %token WHILE IF PRINT END DO THEN ELSE OR AND NOT OVER PLUS MINUS MULTI LESS BIGGER EQUAL ASSIGN LESSEQ BIGEQ LAPREN COMMA RPAREN SEMI START
221 | %nonassoc IFX
222 | %nonassoc ELSE
223 |
224 | %left GE LE EQ NE LESS BIGGER
225 | %left PLUS MINUS
226 | %left MULTI OVER
227 | %nonassoc UMINUS
228 |
229 | %type expitem boolreln stmnt explist
230 |
231 |
232 | %%
233 |
234 | prgmbody :
235 | stmntlist { exit(0); }
236 | ;
237 |
238 | stmntlist :
239 | stmntlist stmnt { ex($2); freeNode($2); }
240 | | /* NULL */
241 | ;
242 |
243 | stmnt :
244 | PRINT expitem SEMI { $$ = opr(PRINT, 1, $2); }
245 | | START explist END { $$ = $2; }
246 | | WHILE expitem DO stmnt { $$ = opr(WHILE, 2, $2, $4); }
247 | | IF expitem THEN stmnt { $$ = opr(IF, 2, $2, $4); }
248 | | IF expitem THEN stmnt ELSE stmnt { $$ = opr(IF, 3, $2, $4, $6); }
249 | | VARIABLE ASSIGN expitem SEMI { $$ = opr(ASSIGN, 2, id($1), $3); }
250 | ;
251 |
252 | explist :
253 | expitem { $$ = $1; }
254 | | explist SEMI expitem { $$ = opr(SEMI, 2, $1, $3); }
255 | ;
256 |
257 | expitem :
258 | NUMBER { $$ = con($1); }
259 | | expitem PLUS expitem { $$ = opr(PLUS, 2, $1, $3); }
260 | | expitem MINUS expitem { $$ = opr(MINUS, 2, $1, $3); }
261 | | expitem MULTI expitem { $$ = opr(MULTI, 2, $1, $3); }
262 | | expitem OVER expitem { $$ = opr(OVER, 2, $1, $3); }
263 | | FALSE { $$ = boole($1); }
264 | | TRUE { $$ = boole($1); }
265 | | VARIABLE { $$ = id($1); }
266 | | boolreln
267 | | LAPREN expitem RPAREN { $$ = $2; }
268 | | expitem OR expitem
269 | | expitem AND expitem
270 | | NOT expitem
271 | ;
272 |
273 | boolreln :
274 | expitem LESS expitem { $$ = opr(LESS, 2, $1, $3); }
275 | | expitem LESSEQ expitem { $$ = opr(LESSEQ, 2, $1, $3); }
276 | | expitem EQUAL expitem { $$ = opr(EQUAL, 2, $1, $3); }
277 | | expitem BIGEQ expitem { $$ = opr(BIGEQ, 2, $1, $3); }
278 | | expitem BIGGER expitem { $$ = opr(BIGGER, 2, $1, $3); }
279 | ;
280 |
281 | %%
282 |
283 | nodeType *con(int value) {
284 | nodeType *p;
285 |
286 | /* allocate node */
287 | if ((p = malloc(sizeof(nodeType))) == NULL)
288 | yyerror("out of memory");
289 |
290 | /* copy information */
291 | p->type = typeCon;
292 | p->con.value = value;
293 |
294 | return p;
295 | }
296 |
297 | nodeType *boole(int boo) {
298 | nodeType *p;
299 |
300 | /* allocate node */
301 | if ((p = malloc(sizeof(nodeType))) == NULL)
302 | yyerror("out of memory");
303 |
304 | /* copy information */
305 | p->type = typeBoolean;
306 | p->boole.boo = boo;
307 |
308 | return p;
309 | }
310 |
311 | nodeType *id(int i) {
312 | nodeType *p;
313 |
314 | /* allocate node */
315 | if ((p = malloc(sizeof(nodeType))) == NULL)
316 | yyerror("out of memory");
317 |
318 | /* copy information */
319 | p->type = typeId;
320 | p->id.i = i;
321 |
322 | return p;
323 | }
324 |
325 | nodeType *opr(int oper, int nops, ...) {
326 | va_list ap;
327 | nodeType *p;
328 | int i;
329 |
330 | /* allocate node, extending op array */
331 | if ((p = malloc(sizeof(nodeType) + (nops-1) * sizeof(nodeType *))) == NULL)
332 | yyerror("out of memory");
333 |
334 | /* copy information */
335 | p->type = typeOpr;
336 | p->opr.oper = oper;
337 | p->opr.nops = nops;
338 | va_start(ap, nops);
339 | for (i = 0; i < nops; i++)
340 | p->opr.op[i] = va_arg(ap, nodeType*);
341 | va_end(ap);
342 | return p;
343 | }
344 |
345 | void freeNode(nodeType *p) {
346 | int i;
347 |
348 | if (!p) return;
349 | if (p->type == typeOpr) {
350 | for (i = 0; i < p->opr.nops; i++)
351 | freeNode(p->opr.op[i]);
352 | }
353 | free (p);
354 | }
355 |
356 | void yyerror(char *s) {
357 | fprintf(stdout, "%s\n", s);
358 | }
359 |
360 | int main(void) {
361 | yyparse();
362 | return 0;
363 | }
364 |
365 | ```
366 |
367 |
368 | ## **Header File**
369 |
370 | ```Yacc
371 |
372 | typedef enum { typeCon, typeId, typeOpr, typeBoolean } nodeEnum;
373 |
374 | /* constants */
375 | typedef struct {
376 | int value; /* value of constant */
377 | } conNodeType;
378 |
379 | typedef struct {
380 | int boo; /* value of constant */
381 | } booNodeType;
382 |
383 | /* identifiers */
384 | typedef struct {
385 | int i; /* subscript to sym array */
386 | } idNodeType;
387 |
388 | /* operators */
389 | typedef struct {
390 | int oper; /* operator */
391 | int nops; /* number of operands */
392 | struct nodeTypeTag *op[1]; /* operands, extended at runtime */
393 | } oprNodeType;
394 |
395 | typedef struct nodeTypeTag {
396 | nodeEnum type; /* type of node */
397 |
398 | union {
399 | conNodeType con; /* constants */
400 | idNodeType id; /* identifiers */
401 | oprNodeType opr; /* operators */
402 | booNodeType boole;
403 | };
404 | } nodeType;
405 |
406 | extern int sym[26];
407 |
408 | ```
409 |
410 |
411 | ## **JavaScript Code Generator**
412 |
413 | ```Yacc
414 |
415 | #include
416 | #include "calc.h"
417 | #include "y.tab.h"
418 |
419 |
420 | int ex(nodeType *p) {
421 |
422 | if (!p) return 0;
423 |
424 | switch(p->type) {
425 |
426 | case typeCon: printf("%d", p->con.value);
427 | break;
428 |
429 | case typeBoolean: printf("%c", p->boole.boo);
430 | break;
431 |
432 | case typeId: printf("var ");
433 | printf("%c", p->id.i + 'a');
434 | break;
435 |
436 |
437 | case typeOpr:
438 |
439 | switch(p->opr.oper) {
440 |
441 | case WHILE: printf("while ("); ex(p->opr.op[0]);
442 | printf(") {"); ex(p->opr.op[1]);
443 | printf(" }");
444 | break;
445 |
446 | case IF: printf("if ("); ex(p->opr.op[0]);
447 | printf(") {"); ex(p->opr.op[1]);
448 | printf(" }");
449 | if (p->opr.nops > 2)
450 | printf("else { "); ex(p->opr.op[2]);
451 | printf(" }");
452 | break;
453 |
454 | case PRINT: printf("console.log( ");
455 | ex(p->opr.op[0]);
456 | printf(" )");
457 | break;
458 |
459 | case SEMI: ex(p->opr.op[0]);
460 | printf(" ; ");
461 | ex(p->opr.op[1]);
462 | break;
463 |
464 | case ASSIGN: printf("var ");
465 | printf("%c = ", p->opr.op[0]->id.i + 'a');
466 | ex(p->opr.op[1]);
467 | break;
468 |
469 | case PLUS: ex(p->opr.op[0]);
470 | printf(" + ");
471 | ex(p->opr.op[1]);
472 | break;
473 |
474 | case MINUS: ex(p->opr.op[0]);
475 | printf(" - ");
476 | ex(p->opr.op[1]);
477 | break;
478 |
479 | case MULTI: ex(p->opr.op[0]);
480 | printf(" * ");
481 | ex(p->opr.op[1]);
482 | break;
483 |
484 | case OVER: ex(p->opr.op[0]);
485 | printf(" / ");
486 | ex(p->opr.op[1]);
487 | break;
488 |
489 | case LESS: ex(p->opr.op[0]);
490 | printf(" < ");
491 | ex(p->opr.op[1]);
492 | break;
493 |
494 | case BIGGER: ex(p->opr.op[0]);
495 | printf(" < ");
496 | ex(p->opr.op[1]);
497 | break;
498 |
499 | case BIGEQ: ex(p->opr.op[0]);
500 | printf(" >= ");
501 | ex(p->opr.op[1]);
502 | break;
503 |
504 | case LESSEQ: ex(p->opr.op[0]);
505 | printf(" <= ");
506 | ex(p->opr.op[1]);
507 | break;
508 |
509 | /*case NE: return ex(p->opr.op[0]) != ex(p->opr.op[1]);*/
510 |
511 | case EQUAL: ex(p->opr.op[0]);
512 | printf(" === ");
513 | ex(p->opr.op[1]);
514 | break;
515 | }
516 | }
517 | return 0;
518 | }
519 |
520 | ```
521 |
522 |
523 | ## **Test Results**
524 |
525 | **1.**
526 |
527 | 
528 |
529 | **2.**
530 |
531 | 
532 |
533 | **3.**
534 |
535 | 
536 |
--------------------------------------------------------------------------------
/calc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandunrajitha/Compiler-Design-and-Implementation-using-lex-and-yacc/6d2089452d02de8977a7a820b64ae4e3d8c93729/calc
--------------------------------------------------------------------------------
/calc.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "calc.h"
3 | #include "y.tab.h"
4 |
5 | int ex(nodeType *p) {
6 | if (!p) return 0;
7 | switch(p->type) {
8 | case typeCon: return p->con.value;
9 | case typeBoolean: return p->boole.boo;
10 | case typeId: return sym[p->id.i];
11 | case typeOpr:
12 | switch(p->opr.oper) {
13 | case WHILE: while(ex(p->opr.op[0])) ex(p->opr.op[1]); return 0;
14 | case IF: if (ex(p->opr.op[0]))
15 | ex(p->opr.op[1]);
16 | else if (p->opr.nops > 2)
17 | ex(p->opr.op[2]);
18 | return 0;
19 | case PRINT: printf("%d\n", ex(p->opr.op[0])); return 0;
20 | case SEMI: ex(p->opr.op[0]); return ex(p->opr.op[1]);
21 | case ASSIGN: return sym[p->opr.op[0]->id.i] = ex(p->opr.op[1]);
22 | case PLUS: return ex(p->opr.op[0]) + ex(p->opr.op[1]);
23 | case MINUS: return ex(p->opr.op[0]) - ex(p->opr.op[1]);
24 | case MULTI: return ex(p->opr.op[0]) * ex(p->opr.op[1]);
25 | case OVER: return ex(p->opr.op[0]) / ex(p->opr.op[1]);
26 | case LESS: return ex(p->opr.op[0]) < ex(p->opr.op[1]);
27 | case BIGGER: return ex(p->opr.op[0]) > ex(p->opr.op[1]);
28 | case BIGEQ: return ex(p->opr.op[0]) >= ex(p->opr.op[1]);
29 | case LESSEQ: return ex(p->opr.op[0]) <= ex(p->opr.op[1]);
30 | /*case NE: return ex(p->opr.op[0]) != ex(p->opr.op[1]);*/
31 | case EQUAL: return ex(p->opr.op[0]) == ex(p->opr.op[1]);
32 | }
33 | }
34 | return 0;
35 | }
36 |
--------------------------------------------------------------------------------
/calc.h:
--------------------------------------------------------------------------------
1 | typedef enum { typeCon, typeId, typeOpr, typeBoolean } nodeEnum;
2 |
3 | /* constants */
4 | typedef struct {
5 | int value; /* value of constant */
6 | } conNodeType;
7 |
8 | typedef struct {
9 | int boo; /* value of constant */
10 | } booNodeType;
11 |
12 | /* identifiers */
13 | typedef struct {
14 | int i; /* subscript to sym array */
15 | } idNodeType;
16 |
17 | /* operators */
18 | typedef struct {
19 | int oper; /* operator */
20 | int nops; /* number of operands */
21 | struct nodeTypeTag *op[1]; /* operands, extended at runtime */
22 | } oprNodeType;
23 |
24 | typedef struct nodeTypeTag {
25 | nodeEnum type; /* type of node */
26 |
27 | union {
28 | conNodeType con; /* constants */
29 | idNodeType id; /* identifiers */
30 | oprNodeType opr; /* operators */
31 | booNodeType boole;
32 | };
33 | } nodeType;
34 |
35 | extern int sym[26];
36 |
--------------------------------------------------------------------------------
/calc.l:
--------------------------------------------------------------------------------
1 | %{
2 | #include
3 | #include "calc.h"
4 | #include "y.tab.h"
5 | void yyerror(char *);
6 | %}
7 |
8 | %%
9 |
10 | [a-z,A-Z] { yylval.sIndex = *yytext - 'a'; return VARIABLE;};
11 | "print" return PRINT;
12 | "begin" return START;
13 | "if" return IF;
14 | "then" return THEN;
15 | "else" return ELSE;
16 | "while" return WHILE;
17 | "do" return DO;
18 | "and" return AND;
19 | "or" return OR;
20 | "true" {yylval.bValue = 1; return TRUE;};
21 | "false" {yylval.bValue = 0; return FALSE;};
22 | [1-9][0-9]* {yylval.iValue = atoi(yytext); return NUMBER;};
23 | "+" return PLUS;
24 | "-" return MINUS;
25 | "*" return MULTI;
26 | "/" return OVER;
27 | ";" return SEMI;
28 | "<" return LESS;
29 | ">" return BIGGER;
30 | "=" return EQUAL;
31 | "(" return LAPREN;
32 | ")" return RPAREN;
33 | ":=" return ASSIGN;
34 | "<=" return LESSEQ;
35 | ">=" return BIGEQ;
36 | [ \t\n]+;
37 | .
38 |
39 | %%
40 |
41 | int yywrap(void) {
42 | return 1;
43 | }
44 |
--------------------------------------------------------------------------------
/calc.y:
--------------------------------------------------------------------------------
1 | %{
2 | #include
3 | #include
4 | #include
5 | #include "calc.h"
6 |
7 | /* prototypes */
8 | nodeType *opr(int oper, int nops, ...);
9 | nodeType *id(int i);
10 | nodeType *con(int value);
11 | nodeType *boole(int value);
12 | void freeNode(nodeType *p);
13 | int ex(nodeType *p);
14 | int yylex(void);
15 |
16 | void yyerror(char *s);
17 | int sym[26];
18 |
19 | %}
20 |
21 | %union {
22 | int iValue; /* integer value */
23 | int bValue;
24 | char sIndex; /* symbol table index */
25 | nodeType *nPtr; /* node pointer */
26 | };
27 |
28 | %token NUMBER
29 | %token TRUE FALSE
30 | %token VARIABLE
31 | %token WHILE IF PRINT END DO THEN ELSE OR AND NOT OVER PLUS MINUS MULTI LESS BIGGER EQUAL ASSIGN LESSEQ BIGEQ LAPREN COMMA RPAREN SEMI START
32 | %nonassoc IFX
33 | %nonassoc ELSE
34 |
35 | %left GE LE EQ NE LESS BIGGER
36 | %left PLUS MINUS
37 | %left MULTI OVER
38 | %nonassoc UMINUS
39 |
40 | %type expitem boolreln stmnt explist
41 |
42 |
43 | %%
44 |
45 | prgmbody :
46 | stmntlist { exit(0); }
47 | ;
48 |
49 | stmntlist :
50 | stmntlist stmnt { ex($2); freeNode($2); }
51 | | /* NULL */
52 | ;
53 |
54 | stmnt :
55 | PRINT expitem SEMI { $$ = opr(PRINT, 1, $2,SEMI); }
56 | | START explist END { $$ = $2; }
57 | | WHILE expitem DO stmnt { $$ = opr(WHILE, 2, $2, $4); }
58 | | IF expitem THEN stmnt { $$ = opr(IF, 2, $2, $4); }
59 | | IF expitem THEN stmnt ELSE stmnt { $$ = opr(IF, 3, $2, $4, $6); }
60 | | VARIABLE ASSIGN expitem SEMI { $$ = opr(ASSIGN, 2, id($1), $3); }
61 | ;
62 |
63 | explist :
64 | expitem { $$ = $1; }
65 | | explist SEMI expitem { $$ = opr(SEMI, 2, $1, $3); }
66 | ;
67 |
68 | expitem :
69 | NUMBER { $$ = con($1); }
70 | | expitem PLUS expitem { $$ = opr(PLUS, 2, $1, $3); }
71 | | expitem MINUS expitem { $$ = opr(MINUS, 2, $1, $3); }
72 | | expitem MULTI expitem { $$ = opr(MULTI, 2, $1, $3); }
73 | | expitem OVER expitem { $$ = opr(OVER, 2, $1, $3); }
74 | | FALSE { $$ = boole($1); }
75 | | TRUE { $$ = boole($1); }
76 | | VARIABLE { $$ = id($1); }
77 | | boolreln
78 | | LAPREN expitem RPAREN { $$ = $2; }
79 | | expitem OR expitem
80 | | expitem AND expitem
81 | | NOT expitem
82 | ;
83 |
84 | boolreln :
85 | expitem LESS expitem { $$ = opr(LESS, 2, $1, $3); }
86 | | expitem LESSEQ expitem { $$ = opr(LESSEQ, 2, $1, $3); }
87 | | expitem EQUAL expitem { $$ = opr(EQUAL, 2, $1, $3); }
88 | | expitem BIGEQ expitem { $$ = opr(BIGEQ, 2, $1, $3); }
89 | | expitem BIGGER expitem { $$ = opr(BIGGER, 2, $1, $3); }
90 | ;
91 |
92 | %%
93 |
94 | nodeType *con(int value) {
95 | nodeType *p;
96 |
97 | /* allocate node */
98 | if ((p = malloc(sizeof(nodeType))) == NULL)
99 | yyerror("out of memory");
100 |
101 | /* copy information */
102 | p->type = typeCon;
103 | p->con.value = value;
104 |
105 | return p;
106 | }
107 |
108 | nodeType *boole(int boo) {
109 | nodeType *p;
110 |
111 | /* allocate node */
112 | if ((p = malloc(sizeof(nodeType))) == NULL)
113 | yyerror("out of memory");
114 |
115 | /* copy information */
116 | p->type = typeBoolean;
117 | p->boole.boo = boo;
118 |
119 | return p;
120 | }
121 |
122 | nodeType *id(int i) {
123 | nodeType *p;
124 |
125 | /* allocate node */
126 | if ((p = malloc(sizeof(nodeType))) == NULL)
127 | yyerror("out of memory");
128 |
129 | /* copy information */
130 | p->type = typeId;
131 | p->id.i = i;
132 |
133 | return p;
134 | }
135 |
136 | nodeType *opr(int oper, int nops, ...) {
137 | va_list ap;
138 | nodeType *p;
139 | int i;
140 |
141 | /* allocate node, extending op array */
142 | if ((p = malloc(sizeof(nodeType) + (nops-1) * sizeof(nodeType *))) == NULL)
143 | yyerror("out of memory");
144 |
145 | /* copy information */
146 | p->type = typeOpr;
147 | p->opr.oper = oper;
148 | p->opr.nops = nops;
149 | va_start(ap, nops);
150 | for (i = 0; i < nops; i++)
151 | p->opr.op[i] = va_arg(ap, nodeType*);
152 | va_end(ap);
153 | return p;
154 | }
155 |
156 | void freeNode(nodeType *p) {
157 | int i;
158 |
159 | if (!p) return;
160 | if (p->type == typeOpr) {
161 | for (i = 0; i < p->opr.nops; i++)
162 | freeNode(p->opr.op[i]);
163 | }
164 | free (p);
165 | }
166 |
167 | void yyerror(char *s) {
168 | fprintf(stdout, "%s\n", s);
169 | }
170 |
171 | int main(void) {
172 | yyparse();
173 | return 0;
174 | }
175 |
--------------------------------------------------------------------------------
/calc3b.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "calc.h"
3 | #include "y.tab.h"
4 |
5 | static int lbl;
6 |
7 | int ex(nodeType *p) {
8 | int lbl1, lbl2;
9 |
10 | if (!p) return 0;
11 | switch(p->type) {
12 | case typeCon:
13 | printf("%d", p->con.value);
14 | break;
15 |
16 | case typeBoolean:
17 | printf("%c", p->boole.boo);
18 | break;
19 |
20 | case typeId:
21 | printf("%c", p->id.i + 'a');
22 | break;
23 |
24 | case typeOpr:
25 | switch(p->opr.oper) {
26 |
27 |
28 | case WHILE: printf("while ("); ex(p->opr.op[0]);
29 | printf(") {"); ex(p->opr.op[1]);
30 | printf("}");
31 | break;
32 |
33 | case IF: printf("if ("); ex(p->opr.op[0]);
34 | printf(") {"); ex(p->opr.op[1]);
35 | printf(" }");
36 | if (p->opr.nops > 2)
37 | printf(" else { "); ex(p->opr.op[2]);
38 | printf(" }");
39 | break;
40 |
41 | case PRINT: printf("console.log( ");
42 | ex(p->opr.op[0]);
43 | printf(" )");
44 | break;
45 |
46 | case SEMI: ex(p->opr.op[0]);
47 | printf(" ; ");
48 | ex(p->opr.op[1]);
49 | break;
50 |
51 | case ASSIGN: printf("var ");
52 | printf("%c = ", p->opr.op[0]->id.i + 'a');
53 | ex(p->opr.op[1]);
54 | break;
55 |
56 | case PLUS: ex(p->opr.op[0]);
57 | printf(" + ");
58 | ex(p->opr.op[1]);
59 | break;
60 |
61 | case MINUS: ex(p->opr.op[0]);
62 | printf(" - ");
63 | ex(p->opr.op[1]);
64 | break;
65 |
66 | case MULTI: ex(p->opr.op[0]);
67 | printf(" * ");
68 | ex(p->opr.op[1]);
69 | break;
70 |
71 | case OVER: ex(p->opr.op[0]);
72 | printf(" / ");
73 | ex(p->opr.op[1]);
74 | break;
75 |
76 | case LESS: ex(p->opr.op[0]);
77 | printf(" < ");
78 | ex(p->opr.op[1]);
79 | break;
80 |
81 | case BIGGER: ex(p->opr.op[0]);
82 | printf(" > ");
83 | ex(p->opr.op[1]);
84 | break;
85 |
86 | case BIGEQ: ex(p->opr.op[0]);
87 | printf(" >= ");
88 | ex(p->opr.op[1]);
89 | break;
90 |
91 | case LESSEQ: ex(p->opr.op[0]);
92 | printf(" <= ");
93 | ex(p->opr.op[1]);
94 | break;
95 |
96 | /*case NE: return ex(p->opr.op[0]) != ex(p->opr.op[1]);*/
97 | case EQUAL: ex(p->opr.op[0]);
98 | printf(" === ");
99 | ex(p->opr.op[1]);
100 | break;
101 | }
102 | }
103 | return 0;
104 | }
105 |
--------------------------------------------------------------------------------
/compile.sh:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | SOURCE=$1
3 | echo $SOURCE | ./calc
4 |
--------------------------------------------------------------------------------
/images/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandunrajitha/Compiler-Design-and-Implementation-using-lex-and-yacc/6d2089452d02de8977a7a820b64ae4e3d8c93729/images/1.png
--------------------------------------------------------------------------------
/images/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandunrajitha/Compiler-Design-and-Implementation-using-lex-and-yacc/6d2089452d02de8977a7a820b64ae4e3d8c93729/images/2.png
--------------------------------------------------------------------------------
/images/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandunrajitha/Compiler-Design-and-Implementation-using-lex-and-yacc/6d2089452d02de8977a7a820b64ae4e3d8c93729/images/3.png
--------------------------------------------------------------------------------
/images/derivation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandunrajitha/Compiler-Design-and-Implementation-using-lex-and-yacc/6d2089452d02de8977a7a820b64ae4e3d8c93729/images/derivation.png
--------------------------------------------------------------------------------
/images/grammar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandunrajitha/Compiler-Design-and-Implementation-using-lex-and-yacc/6d2089452d02de8977a7a820b64ae4e3d8c93729/images/grammar.png
--------------------------------------------------------------------------------
/images/ndfa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandunrajitha/Compiler-Design-and-Implementation-using-lex-and-yacc/6d2089452d02de8977a7a820b64ae4e3d8c93729/images/ndfa.png
--------------------------------------------------------------------------------
/images/test1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandunrajitha/Compiler-Design-and-Implementation-using-lex-and-yacc/6d2089452d02de8977a7a820b64ae4e3d8c93729/images/test1.png
--------------------------------------------------------------------------------
/images/test2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandunrajitha/Compiler-Design-and-Implementation-using-lex-and-yacc/6d2089452d02de8977a7a820b64ae4e3d8c93729/images/test2.png
--------------------------------------------------------------------------------
/images/test3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandunrajitha/Compiler-Design-and-Implementation-using-lex-and-yacc/6d2089452d02de8977a7a820b64ae4e3d8c93729/images/test3.png
--------------------------------------------------------------------------------
/lex.yy.c:
--------------------------------------------------------------------------------
1 |
2 | #line 3 "lex.yy.c"
3 |
4 | #define YY_INT_ALIGNED short int
5 |
6 | /* A lexical scanner generated by flex */
7 |
8 | #define FLEX_SCANNER
9 | #define YY_FLEX_MAJOR_VERSION 2
10 | #define YY_FLEX_MINOR_VERSION 5
11 | #define YY_FLEX_SUBMINOR_VERSION 35
12 | #if YY_FLEX_SUBMINOR_VERSION > 0
13 | #define FLEX_BETA
14 | #endif
15 |
16 | /* First, we deal with platform-specific or compiler-specific issues. */
17 |
18 | /* begin standard C headers. */
19 | #include
20 | #include
21 | #include
22 | #include
23 |
24 | /* end standard C headers. */
25 |
26 | /* flex integer type definitions */
27 |
28 | #ifndef FLEXINT_H
29 | #define FLEXINT_H
30 |
31 | /* C99 systems have . Non-C99 systems may or may not. */
32 |
33 | #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
34 |
35 | /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
36 | * if you want the limit (max/min) macros for int types.
37 | */
38 | #ifndef __STDC_LIMIT_MACROS
39 | #define __STDC_LIMIT_MACROS 1
40 | #endif
41 |
42 | #include
43 | typedef int8_t flex_int8_t;
44 | typedef uint8_t flex_uint8_t;
45 | typedef int16_t flex_int16_t;
46 | typedef uint16_t flex_uint16_t;
47 | typedef int32_t flex_int32_t;
48 | typedef uint32_t flex_uint32_t;
49 | typedef uint64_t flex_uint64_t;
50 | #else
51 | typedef signed char flex_int8_t;
52 | typedef short int flex_int16_t;
53 | typedef int flex_int32_t;
54 | typedef unsigned char flex_uint8_t;
55 | typedef unsigned short int flex_uint16_t;
56 | typedef unsigned int flex_uint32_t;
57 | #endif /* ! C99 */
58 |
59 | /* Limits of integral types. */
60 | #ifndef INT8_MIN
61 | #define INT8_MIN (-128)
62 | #endif
63 | #ifndef INT16_MIN
64 | #define INT16_MIN (-32767-1)
65 | #endif
66 | #ifndef INT32_MIN
67 | #define INT32_MIN (-2147483647-1)
68 | #endif
69 | #ifndef INT8_MAX
70 | #define INT8_MAX (127)
71 | #endif
72 | #ifndef INT16_MAX
73 | #define INT16_MAX (32767)
74 | #endif
75 | #ifndef INT32_MAX
76 | #define INT32_MAX (2147483647)
77 | #endif
78 | #ifndef UINT8_MAX
79 | #define UINT8_MAX (255U)
80 | #endif
81 | #ifndef UINT16_MAX
82 | #define UINT16_MAX (65535U)
83 | #endif
84 | #ifndef UINT32_MAX
85 | #define UINT32_MAX (4294967295U)
86 | #endif
87 |
88 | #endif /* ! FLEXINT_H */
89 |
90 | #ifdef __cplusplus
91 |
92 | /* The "const" storage-class-modifier is valid. */
93 | #define YY_USE_CONST
94 |
95 | #else /* ! __cplusplus */
96 |
97 | /* C99 requires __STDC__ to be defined as 1. */
98 | #if defined (__STDC__)
99 |
100 | #define YY_USE_CONST
101 |
102 | #endif /* defined (__STDC__) */
103 | #endif /* ! __cplusplus */
104 |
105 | #ifdef YY_USE_CONST
106 | #define yyconst const
107 | #else
108 | #define yyconst
109 | #endif
110 |
111 | /* Returned upon end-of-file. */
112 | #define YY_NULL 0
113 |
114 | /* Promotes a possibly negative, possibly signed char to an unsigned
115 | * integer for use as an array index. If the signed char is negative,
116 | * we want to instead treat it as an 8-bit unsigned char, hence the
117 | * double cast.
118 | */
119 | #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
120 |
121 | /* Enter a start condition. This macro really ought to take a parameter,
122 | * but we do it the disgusting crufty way forced on us by the ()-less
123 | * definition of BEGIN.
124 | */
125 | #define BEGIN (yy_start) = 1 + 2 *
126 |
127 | /* Translate the current start state into a value that can be later handed
128 | * to BEGIN to return to the state. The YYSTATE alias is for lex
129 | * compatibility.
130 | */
131 | #define YY_START (((yy_start) - 1) / 2)
132 | #define YYSTATE YY_START
133 |
134 | /* Action number for EOF rule of a given start state. */
135 | #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
136 |
137 | /* Special action meaning "start processing a new file". */
138 | #define YY_NEW_FILE yyrestart(yyin )
139 |
140 | #define YY_END_OF_BUFFER_CHAR 0
141 |
142 | /* Size of default input buffer. */
143 | #ifndef YY_BUF_SIZE
144 | #define YY_BUF_SIZE 16384
145 | #endif
146 |
147 | /* The state buf must be large enough to hold one state per character in the main buffer.
148 | */
149 | #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
150 |
151 | #ifndef YY_TYPEDEF_YY_BUFFER_STATE
152 | #define YY_TYPEDEF_YY_BUFFER_STATE
153 | typedef struct yy_buffer_state *YY_BUFFER_STATE;
154 | #endif
155 |
156 | #ifndef YY_TYPEDEF_YY_SIZE_T
157 | #define YY_TYPEDEF_YY_SIZE_T
158 | typedef size_t yy_size_t;
159 | #endif
160 |
161 | extern yy_size_t yyleng;
162 |
163 | extern FILE *yyin, *yyout;
164 |
165 | #define EOB_ACT_CONTINUE_SCAN 0
166 | #define EOB_ACT_END_OF_FILE 1
167 | #define EOB_ACT_LAST_MATCH 2
168 |
169 | #define YY_LESS_LINENO(n)
170 |
171 | /* Return all but the first "n" matched characters back to the input stream. */
172 | #define yyless(n) \
173 | do \
174 | { \
175 | /* Undo effects of setting up yytext. */ \
176 | int yyless_macro_arg = (n); \
177 | YY_LESS_LINENO(yyless_macro_arg);\
178 | *yy_cp = (yy_hold_char); \
179 | YY_RESTORE_YY_MORE_OFFSET \
180 | (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
181 | YY_DO_BEFORE_ACTION; /* set up yytext again */ \
182 | } \
183 | while ( 0 )
184 |
185 | #define unput(c) yyunput( c, (yytext_ptr) )
186 |
187 | #ifndef YY_STRUCT_YY_BUFFER_STATE
188 | #define YY_STRUCT_YY_BUFFER_STATE
189 | struct yy_buffer_state
190 | {
191 | FILE *yy_input_file;
192 |
193 | char *yy_ch_buf; /* input buffer */
194 | char *yy_buf_pos; /* current position in input buffer */
195 |
196 | /* Size of input buffer in bytes, not including room for EOB
197 | * characters.
198 | */
199 | yy_size_t yy_buf_size;
200 |
201 | /* Number of characters read into yy_ch_buf, not including EOB
202 | * characters.
203 | */
204 | yy_size_t yy_n_chars;
205 |
206 | /* Whether we "own" the buffer - i.e., we know we created it,
207 | * and can realloc() it to grow it, and should free() it to
208 | * delete it.
209 | */
210 | int yy_is_our_buffer;
211 |
212 | /* Whether this is an "interactive" input source; if so, and
213 | * if we're using stdio for input, then we want to use getc()
214 | * instead of fread(), to make sure we stop fetching input after
215 | * each newline.
216 | */
217 | int yy_is_interactive;
218 |
219 | /* Whether we're considered to be at the beginning of a line.
220 | * If so, '^' rules will be active on the next match, otherwise
221 | * not.
222 | */
223 | int yy_at_bol;
224 |
225 | int yy_bs_lineno; /**< The line count. */
226 | int yy_bs_column; /**< The column count. */
227 |
228 | /* Whether to try to fill the input buffer when we reach the
229 | * end of it.
230 | */
231 | int yy_fill_buffer;
232 |
233 | int yy_buffer_status;
234 |
235 | #define YY_BUFFER_NEW 0
236 | #define YY_BUFFER_NORMAL 1
237 | /* When an EOF's been seen but there's still some text to process
238 | * then we mark the buffer as YY_EOF_PENDING, to indicate that we
239 | * shouldn't try reading from the input source any more. We might
240 | * still have a bunch of tokens to match, though, because of
241 | * possible backing-up.
242 | *
243 | * When we actually see the EOF, we change the status to "new"
244 | * (via yyrestart()), so that the user can continue scanning by
245 | * just pointing yyin at a new input file.
246 | */
247 | #define YY_BUFFER_EOF_PENDING 2
248 |
249 | };
250 | #endif /* !YY_STRUCT_YY_BUFFER_STATE */
251 |
252 | /* Stack of input buffers. */
253 | static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
254 | static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
255 | static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
256 |
257 | /* We provide macros for accessing buffer states in case in the
258 | * future we want to put the buffer states in a more general
259 | * "scanner state".
260 | *
261 | * Returns the top of the stack, or NULL.
262 | */
263 | #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
264 | ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
265 | : NULL)
266 |
267 | /* Same as previous macro, but useful when we know that the buffer stack is not
268 | * NULL or when we need an lvalue. For internal use only.
269 | */
270 | #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
271 |
272 | /* yy_hold_char holds the character lost when yytext is formed. */
273 | static char yy_hold_char;
274 | static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */
275 | yy_size_t yyleng;
276 |
277 | /* Points to current character in buffer. */
278 | static char *yy_c_buf_p = (char *) 0;
279 | static int yy_init = 0; /* whether we need to initialize */
280 | static int yy_start = 0; /* start state number */
281 |
282 | /* Flag which is used to allow yywrap()'s to do buffer switches
283 | * instead of setting up a fresh yyin. A bit of a hack ...
284 | */
285 | static int yy_did_buffer_switch_on_eof;
286 |
287 | void yyrestart (FILE *input_file );
288 | void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer );
289 | YY_BUFFER_STATE yy_create_buffer (FILE *file,int size );
290 | void yy_delete_buffer (YY_BUFFER_STATE b );
291 | void yy_flush_buffer (YY_BUFFER_STATE b );
292 | void yypush_buffer_state (YY_BUFFER_STATE new_buffer );
293 | void yypop_buffer_state (void );
294 |
295 | static void yyensure_buffer_stack (void );
296 | static void yy_load_buffer_state (void );
297 | static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
298 |
299 | #define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
300 |
301 | YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
302 | YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
303 | YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len );
304 |
305 | void *yyalloc (yy_size_t );
306 | void *yyrealloc (void *,yy_size_t );
307 | void yyfree (void * );
308 |
309 | #define yy_new_buffer yy_create_buffer
310 |
311 | #define yy_set_interactive(is_interactive) \
312 | { \
313 | if ( ! YY_CURRENT_BUFFER ){ \
314 | yyensure_buffer_stack (); \
315 | YY_CURRENT_BUFFER_LVALUE = \
316 | yy_create_buffer(yyin,YY_BUF_SIZE ); \
317 | } \
318 | YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
319 | }
320 |
321 | #define yy_set_bol(at_bol) \
322 | { \
323 | if ( ! YY_CURRENT_BUFFER ){\
324 | yyensure_buffer_stack (); \
325 | YY_CURRENT_BUFFER_LVALUE = \
326 | yy_create_buffer(yyin,YY_BUF_SIZE ); \
327 | } \
328 | YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
329 | }
330 |
331 | #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
332 |
333 | /* Begin user sect3 */
334 |
335 | typedef unsigned char YY_CHAR;
336 |
337 | FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
338 |
339 | typedef int yy_state_type;
340 |
341 | extern int yylineno;
342 |
343 | int yylineno = 1;
344 |
345 | extern char *yytext;
346 | #define yytext_ptr yytext
347 |
348 | static yy_state_type yy_get_previous_state (void );
349 | static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
350 | static int yy_get_next_buffer (void );
351 | static void yy_fatal_error (yyconst char msg[] );
352 |
353 | /* Done after the current pattern has been matched and before the
354 | * corresponding action - sets up yytext.
355 | */
356 | #define YY_DO_BEFORE_ACTION \
357 | (yytext_ptr) = yy_bp; \
358 | yyleng = (yy_size_t) (yy_cp - yy_bp); \
359 | (yy_hold_char) = *yy_cp; \
360 | *yy_cp = '\0'; \
361 | (yy_c_buf_p) = yy_cp;
362 |
363 | #define YY_NUM_RULES 29
364 | #define YY_END_OF_BUFFER 30
365 | /* This struct is not used in this scanner,
366 | but its presence is necessary. */
367 | struct yy_trans_info
368 | {
369 | flex_int32_t yy_verify;
370 | flex_int32_t yy_nxt;
371 | };
372 | static yyconst flex_int16_t yy_accept[67] =
373 | { 0,
374 | 0, 0, 30, 28, 28, 29, 22, 23, 16, 14,
375 | 1, 15, 17, 13, 28, 18, 19, 21, 20, 1,
376 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
377 | 27, 13, 24, 25, 26, 0, 0, 8, 0, 0,
378 | 4, 10, 0, 0, 0, 0, 9, 0, 0, 0,
379 | 0, 0, 0, 0, 0, 6, 0, 0, 5, 11,
380 | 0, 3, 12, 2, 7, 0
381 | } ;
382 |
383 | static yyconst flex_int32_t yy_ec[256] =
384 | { 0,
385 | 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
386 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
387 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
388 | 1, 2, 1, 1, 1, 1, 1, 1, 1, 4,
389 | 5, 6, 7, 8, 9, 1, 10, 11, 12, 12,
390 | 12, 12, 12, 12, 12, 12, 12, 13, 14, 15,
391 | 16, 17, 1, 1, 8, 8, 8, 8, 8, 8,
392 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
393 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
394 | 1, 1, 1, 1, 1, 1, 18, 19, 8, 20,
395 |
396 | 21, 22, 23, 24, 25, 8, 8, 26, 8, 27,
397 | 28, 29, 8, 30, 31, 32, 33, 8, 34, 8,
398 | 8, 8, 1, 1, 1, 1, 1, 1, 1, 1,
399 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
400 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
401 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
402 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
403 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
404 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
405 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
406 |
407 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
408 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
409 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
410 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
411 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
412 | 1, 1, 1, 1, 1
413 | } ;
414 |
415 | static yyconst flex_int32_t yy_meta[35] =
416 | { 0,
417 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
418 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
419 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
420 | 1, 1, 1, 1
421 | } ;
422 |
423 | static yyconst flex_int16_t yy_base[67] =
424 | { 0,
425 | 0, 0, 81, 82, 33, 35, 82, 82, 82, 82,
426 | 82, 82, 82, 28, 64, 82, 63, 82, 62, 50,
427 | 55, 47, 48, 55, 50, 41, 40, 18, 45, 41,
428 | 82, 34, 82, 82, 82, 48, 44, 82, 35, 39,
429 | 82, 82, 39, 42, 29, 36, 82, 35, 38, 27,
430 | 30, 29, 33, 27, 25, 82, 30, 18, 82, 82,
431 | 20, 82, 82, 82, 82, 82
432 | } ;
433 |
434 | static yyconst flex_int16_t yy_def[67] =
435 | { 0,
436 | 66, 1, 66, 66, 66, 66, 66, 66, 66, 66,
437 | 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
438 | 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
439 | 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
440 | 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
441 | 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
442 | 66, 66, 66, 66, 66, 0
443 | } ;
444 |
445 | static yyconst flex_int16_t yy_nxt[117] =
446 | { 0,
447 | 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
448 | 4, 14, 15, 16, 17, 18, 19, 20, 21, 22,
449 | 23, 24, 11, 11, 25, 11, 11, 26, 27, 11,
450 | 11, 28, 11, 29, 30, 30, 30, 30, 32, 32,
451 | 65, 44, 30, 30, 32, 32, 31, 45, 31, 64,
452 | 63, 62, 61, 60, 31, 59, 58, 57, 56, 55,
453 | 54, 53, 52, 51, 50, 49, 48, 47, 46, 43,
454 | 42, 41, 40, 39, 38, 37, 36, 35, 34, 33,
455 | 66, 3, 66, 66, 66, 66, 66, 66, 66, 66,
456 | 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
457 |
458 | 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
459 | 66, 66, 66, 66, 66, 66
460 | } ;
461 |
462 | static yyconst flex_int16_t yy_chk[117] =
463 | { 0,
464 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
465 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
466 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
467 | 1, 1, 1, 1, 5, 5, 6, 6, 14, 14,
468 | 61, 28, 30, 30, 32, 32, 5, 28, 6, 58,
469 | 57, 55, 54, 53, 30, 52, 51, 50, 49, 48,
470 | 46, 45, 44, 43, 40, 39, 37, 36, 29, 27,
471 | 26, 25, 24, 23, 22, 21, 20, 19, 17, 15,
472 | 3, 66, 66, 66, 66, 66, 66, 66, 66, 66,
473 | 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
474 |
475 | 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
476 | 66, 66, 66, 66, 66, 66
477 | } ;
478 |
479 | static yy_state_type yy_last_accepting_state;
480 | static char *yy_last_accepting_cpos;
481 |
482 | extern int yy_flex_debug;
483 | int yy_flex_debug = 0;
484 |
485 | /* The intent behind this definition is that it'll catch
486 | * any uses of REJECT which flex missed.
487 | */
488 | #define REJECT reject_used_but_not_detected
489 | #define yymore() yymore_used_but_not_detected
490 | #define YY_MORE_ADJ 0
491 | #define YY_RESTORE_YY_MORE_OFFSET
492 | char *yytext;
493 | #line 1 "calc.l"
494 | #line 2 "calc.l"
495 | #include
496 | #include "calc.h"
497 | #include "y.tab.h"
498 | void yyerror(char *);
499 | #line 500 "lex.yy.c"
500 |
501 | #define INITIAL 0
502 |
503 | #ifndef YY_NO_UNISTD_H
504 | /* Special case for "unistd.h", since it is non-ANSI. We include it way
505 | * down here because we want the user's section 1 to have been scanned first.
506 | * The user has a chance to override it with an option.
507 | */
508 | #include
509 | #endif
510 |
511 | #ifndef YY_EXTRA_TYPE
512 | #define YY_EXTRA_TYPE void *
513 | #endif
514 |
515 | static int yy_init_globals (void );
516 |
517 | /* Accessor methods to globals.
518 | These are made visible to non-reentrant scanners for convenience. */
519 |
520 | int yylex_destroy (void );
521 |
522 | int yyget_debug (void );
523 |
524 | void yyset_debug (int debug_flag );
525 |
526 | YY_EXTRA_TYPE yyget_extra (void );
527 |
528 | void yyset_extra (YY_EXTRA_TYPE user_defined );
529 |
530 | FILE *yyget_in (void );
531 |
532 | void yyset_in (FILE * in_str );
533 |
534 | FILE *yyget_out (void );
535 |
536 | void yyset_out (FILE * out_str );
537 |
538 | yy_size_t yyget_leng (void );
539 |
540 | char *yyget_text (void );
541 |
542 | int yyget_lineno (void );
543 |
544 | void yyset_lineno (int line_number );
545 |
546 | /* Macros after this point can all be overridden by user definitions in
547 | * section 1.
548 | */
549 |
550 | #ifndef YY_SKIP_YYWRAP
551 | #ifdef __cplusplus
552 | extern "C" int yywrap (void );
553 | #else
554 | extern int yywrap (void );
555 | #endif
556 | #endif
557 |
558 | static void yyunput (int c,char *buf_ptr );
559 |
560 | #ifndef yytext_ptr
561 | static void yy_flex_strncpy (char *,yyconst char *,int );
562 | #endif
563 |
564 | #ifdef YY_NEED_STRLEN
565 | static int yy_flex_strlen (yyconst char * );
566 | #endif
567 |
568 | #ifndef YY_NO_INPUT
569 |
570 | #ifdef __cplusplus
571 | static int yyinput (void );
572 | #else
573 | static int input (void );
574 | #endif
575 |
576 | #endif
577 |
578 | /* Amount of stuff to slurp up with each read. */
579 | #ifndef YY_READ_BUF_SIZE
580 | #define YY_READ_BUF_SIZE 8192
581 | #endif
582 |
583 | /* Copy whatever the last rule matched to the standard output. */
584 | #ifndef ECHO
585 | /* This used to be an fputs(), but since the string might contain NUL's,
586 | * we now use fwrite().
587 | */
588 | #define ECHO fwrite( yytext, yyleng, 1, yyout )
589 | #endif
590 |
591 | /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
592 | * is returned in "result".
593 | */
594 | #ifndef YY_INPUT
595 | #define YY_INPUT(buf,result,max_size) \
596 | if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
597 | { \
598 | int c = '*'; \
599 | yy_size_t n; \
600 | for ( n = 0; n < max_size && \
601 | (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
602 | buf[n] = (char) c; \
603 | if ( c == '\n' ) \
604 | buf[n++] = (char) c; \
605 | if ( c == EOF && ferror( yyin ) ) \
606 | YY_FATAL_ERROR( "input in flex scanner failed" ); \
607 | result = n; \
608 | } \
609 | else \
610 | { \
611 | errno=0; \
612 | while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
613 | { \
614 | if( errno != EINTR) \
615 | { \
616 | YY_FATAL_ERROR( "input in flex scanner failed" ); \
617 | break; \
618 | } \
619 | errno=0; \
620 | clearerr(yyin); \
621 | } \
622 | }\
623 | \
624 |
625 | #endif
626 |
627 | /* No semi-colon after return; correct usage is to write "yyterminate();" -
628 | * we don't want an extra ';' after the "return" because that will cause
629 | * some compilers to complain about unreachable statements.
630 | */
631 | #ifndef yyterminate
632 | #define yyterminate() return YY_NULL
633 | #endif
634 |
635 | /* Number of entries by which start-condition stack grows. */
636 | #ifndef YY_START_STACK_INCR
637 | #define YY_START_STACK_INCR 25
638 | #endif
639 |
640 | /* Report a fatal error. */
641 | #ifndef YY_FATAL_ERROR
642 | #define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
643 | #endif
644 |
645 | /* end tables serialization structures and prototypes */
646 |
647 | /* Default declaration of generated scanner - a define so the user can
648 | * easily add parameters.
649 | */
650 | #ifndef YY_DECL
651 | #define YY_DECL_IS_OURS 1
652 |
653 | extern int yylex (void);
654 |
655 | #define YY_DECL int yylex (void)
656 | #endif /* !YY_DECL */
657 |
658 | /* Code executed at the beginning of each rule, after yytext and yyleng
659 | * have been set up.
660 | */
661 | #ifndef YY_USER_ACTION
662 | #define YY_USER_ACTION
663 | #endif
664 |
665 | /* Code executed at the end of each rule. */
666 | #ifndef YY_BREAK
667 | #define YY_BREAK break;
668 | #endif
669 |
670 | #define YY_RULE_SETUP \
671 | YY_USER_ACTION
672 |
673 | /** The main scanner function which does all the work.
674 | */
675 | YY_DECL
676 | {
677 | register yy_state_type yy_current_state;
678 | register char *yy_cp, *yy_bp;
679 | register int yy_act;
680 |
681 | #line 8 "calc.l"
682 |
683 |
684 | #line 685 "lex.yy.c"
685 |
686 | if ( !(yy_init) )
687 | {
688 | (yy_init) = 1;
689 |
690 | #ifdef YY_USER_INIT
691 | YY_USER_INIT;
692 | #endif
693 |
694 | if ( ! (yy_start) )
695 | (yy_start) = 1; /* first start state */
696 |
697 | if ( ! yyin )
698 | yyin = stdin;
699 |
700 | if ( ! yyout )
701 | yyout = stdout;
702 |
703 | if ( ! YY_CURRENT_BUFFER ) {
704 | yyensure_buffer_stack ();
705 | YY_CURRENT_BUFFER_LVALUE =
706 | yy_create_buffer(yyin,YY_BUF_SIZE );
707 | }
708 |
709 | yy_load_buffer_state( );
710 | }
711 |
712 | while ( 1 ) /* loops until end-of-file is reached */
713 | {
714 | yy_cp = (yy_c_buf_p);
715 |
716 | /* Support of yytext. */
717 | *yy_cp = (yy_hold_char);
718 |
719 | /* yy_bp points to the position in yy_ch_buf of the start of
720 | * the current run.
721 | */
722 | yy_bp = yy_cp;
723 |
724 | yy_current_state = (yy_start);
725 | yy_match:
726 | do
727 | {
728 | register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
729 | if ( yy_accept[yy_current_state] )
730 | {
731 | (yy_last_accepting_state) = yy_current_state;
732 | (yy_last_accepting_cpos) = yy_cp;
733 | }
734 | while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
735 | {
736 | yy_current_state = (int) yy_def[yy_current_state];
737 | if ( yy_current_state >= 67 )
738 | yy_c = yy_meta[(unsigned int) yy_c];
739 | }
740 | yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
741 | ++yy_cp;
742 | }
743 | while ( yy_base[yy_current_state] != 82 );
744 |
745 | yy_find_action:
746 | yy_act = yy_accept[yy_current_state];
747 | if ( yy_act == 0 )
748 | { /* have to back up */
749 | yy_cp = (yy_last_accepting_cpos);
750 | yy_current_state = (yy_last_accepting_state);
751 | yy_act = yy_accept[yy_current_state];
752 | }
753 |
754 | YY_DO_BEFORE_ACTION;
755 |
756 | do_action: /* This label is used only to access EOF actions. */
757 |
758 | switch ( yy_act )
759 | { /* beginning of action switch */
760 | case 0: /* must back up */
761 | /* undo the effects of YY_DO_BEFORE_ACTION */
762 | *yy_cp = (yy_hold_char);
763 | yy_cp = (yy_last_accepting_cpos);
764 | yy_current_state = (yy_last_accepting_state);
765 | goto yy_find_action;
766 |
767 | case 1:
768 | YY_RULE_SETUP
769 | #line 10 "calc.l"
770 | { yylval.sIndex = *yytext - 'a'; return VARIABLE;};
771 | YY_BREAK
772 | case 2:
773 | YY_RULE_SETUP
774 | #line 11 "calc.l"
775 | return PRINT;
776 | YY_BREAK
777 | case 3:
778 | YY_RULE_SETUP
779 | #line 12 "calc.l"
780 | return START;
781 | YY_BREAK
782 | case 4:
783 | YY_RULE_SETUP
784 | #line 13 "calc.l"
785 | return IF;
786 | YY_BREAK
787 | case 5:
788 | YY_RULE_SETUP
789 | #line 14 "calc.l"
790 | return THEN;
791 | YY_BREAK
792 | case 6:
793 | YY_RULE_SETUP
794 | #line 15 "calc.l"
795 | return ELSE;
796 | YY_BREAK
797 | case 7:
798 | YY_RULE_SETUP
799 | #line 16 "calc.l"
800 | return WHILE;
801 | YY_BREAK
802 | case 8:
803 | YY_RULE_SETUP
804 | #line 17 "calc.l"
805 | return DO;
806 | YY_BREAK
807 | case 9:
808 | YY_RULE_SETUP
809 | #line 18 "calc.l"
810 | return AND;
811 | YY_BREAK
812 | case 10:
813 | YY_RULE_SETUP
814 | #line 19 "calc.l"
815 | return OR;
816 | YY_BREAK
817 | case 11:
818 | YY_RULE_SETUP
819 | #line 20 "calc.l"
820 | {yylval.bValue = 1; return TRUE;};
821 | YY_BREAK
822 | case 12:
823 | YY_RULE_SETUP
824 | #line 21 "calc.l"
825 | {yylval.bValue = 0; return FALSE;};
826 | YY_BREAK
827 | case 13:
828 | YY_RULE_SETUP
829 | #line 22 "calc.l"
830 | {yylval.iValue = atoi(yytext); return NUMBER;};
831 | YY_BREAK
832 | case 14:
833 | YY_RULE_SETUP
834 | #line 23 "calc.l"
835 | return PLUS;
836 | YY_BREAK
837 | case 15:
838 | YY_RULE_SETUP
839 | #line 24 "calc.l"
840 | return MINUS;
841 | YY_BREAK
842 | case 16:
843 | YY_RULE_SETUP
844 | #line 25 "calc.l"
845 | return MULTI;
846 | YY_BREAK
847 | case 17:
848 | YY_RULE_SETUP
849 | #line 26 "calc.l"
850 | return OVER;
851 | YY_BREAK
852 | case 18:
853 | YY_RULE_SETUP
854 | #line 27 "calc.l"
855 | return SEMI;
856 | YY_BREAK
857 | case 19:
858 | YY_RULE_SETUP
859 | #line 28 "calc.l"
860 | return LESS;
861 | YY_BREAK
862 | case 20:
863 | YY_RULE_SETUP
864 | #line 29 "calc.l"
865 | return BIGGER;
866 | YY_BREAK
867 | case 21:
868 | YY_RULE_SETUP
869 | #line 30 "calc.l"
870 | return EQUAL;
871 | YY_BREAK
872 | case 22:
873 | YY_RULE_SETUP
874 | #line 31 "calc.l"
875 | return LAPREN;
876 | YY_BREAK
877 | case 23:
878 | YY_RULE_SETUP
879 | #line 32 "calc.l"
880 | return RPAREN;
881 | YY_BREAK
882 | case 24:
883 | YY_RULE_SETUP
884 | #line 33 "calc.l"
885 | return ASSIGN;
886 | YY_BREAK
887 | case 25:
888 | YY_RULE_SETUP
889 | #line 34 "calc.l"
890 | return LESSEQ;
891 | YY_BREAK
892 | case 26:
893 | YY_RULE_SETUP
894 | #line 35 "calc.l"
895 | return BIGEQ;
896 | YY_BREAK
897 | case 27:
898 | /* rule 27 can match eol */
899 | YY_RULE_SETUP
900 | #line 36 "calc.l"
901 |
902 | YY_BREAK
903 | case 28:
904 | YY_RULE_SETUP
905 | #line 37 "calc.l"
906 |
907 | YY_BREAK
908 | case 29:
909 | YY_RULE_SETUP
910 | #line 39 "calc.l"
911 | ECHO;
912 | YY_BREAK
913 | #line 914 "lex.yy.c"
914 | case YY_STATE_EOF(INITIAL):
915 | yyterminate();
916 |
917 | case YY_END_OF_BUFFER:
918 | {
919 | /* Amount of text matched not including the EOB char. */
920 | int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
921 |
922 | /* Undo the effects of YY_DO_BEFORE_ACTION. */
923 | *yy_cp = (yy_hold_char);
924 | YY_RESTORE_YY_MORE_OFFSET
925 |
926 | if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
927 | {
928 | /* We're scanning a new file or input source. It's
929 | * possible that this happened because the user
930 | * just pointed yyin at a new source and called
931 | * yylex(). If so, then we have to assure
932 | * consistency between YY_CURRENT_BUFFER and our
933 | * globals. Here is the right place to do so, because
934 | * this is the first action (other than possibly a
935 | * back-up) that will match for the new input source.
936 | */
937 | (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
938 | YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
939 | YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
940 | }
941 |
942 | /* Note that here we test for yy_c_buf_p "<=" to the position
943 | * of the first EOB in the buffer, since yy_c_buf_p will
944 | * already have been incremented past the NUL character
945 | * (since all states make transitions on EOB to the
946 | * end-of-buffer state). Contrast this with the test
947 | * in input().
948 | */
949 | if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
950 | { /* This was really a NUL. */
951 | yy_state_type yy_next_state;
952 |
953 | (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
954 |
955 | yy_current_state = yy_get_previous_state( );
956 |
957 | /* Okay, we're now positioned to make the NUL
958 | * transition. We couldn't have
959 | * yy_get_previous_state() go ahead and do it
960 | * for us because it doesn't know how to deal
961 | * with the possibility of jamming (and we don't
962 | * want to build jamming into it because then it
963 | * will run more slowly).
964 | */
965 |
966 | yy_next_state = yy_try_NUL_trans( yy_current_state );
967 |
968 | yy_bp = (yytext_ptr) + YY_MORE_ADJ;
969 |
970 | if ( yy_next_state )
971 | {
972 | /* Consume the NUL. */
973 | yy_cp = ++(yy_c_buf_p);
974 | yy_current_state = yy_next_state;
975 | goto yy_match;
976 | }
977 |
978 | else
979 | {
980 | yy_cp = (yy_c_buf_p);
981 | goto yy_find_action;
982 | }
983 | }
984 |
985 | else switch ( yy_get_next_buffer( ) )
986 | {
987 | case EOB_ACT_END_OF_FILE:
988 | {
989 | (yy_did_buffer_switch_on_eof) = 0;
990 |
991 | if ( yywrap( ) )
992 | {
993 | /* Note: because we've taken care in
994 | * yy_get_next_buffer() to have set up
995 | * yytext, we can now set up
996 | * yy_c_buf_p so that if some total
997 | * hoser (like flex itself) wants to
998 | * call the scanner after we return the
999 | * YY_NULL, it'll still work - another
1000 | * YY_NULL will get returned.
1001 | */
1002 | (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
1003 |
1004 | yy_act = YY_STATE_EOF(YY_START);
1005 | goto do_action;
1006 | }
1007 |
1008 | else
1009 | {
1010 | if ( ! (yy_did_buffer_switch_on_eof) )
1011 | YY_NEW_FILE;
1012 | }
1013 | break;
1014 | }
1015 |
1016 | case EOB_ACT_CONTINUE_SCAN:
1017 | (yy_c_buf_p) =
1018 | (yytext_ptr) + yy_amount_of_matched_text;
1019 |
1020 | yy_current_state = yy_get_previous_state( );
1021 |
1022 | yy_cp = (yy_c_buf_p);
1023 | yy_bp = (yytext_ptr) + YY_MORE_ADJ;
1024 | goto yy_match;
1025 |
1026 | case EOB_ACT_LAST_MATCH:
1027 | (yy_c_buf_p) =
1028 | &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
1029 |
1030 | yy_current_state = yy_get_previous_state( );
1031 |
1032 | yy_cp = (yy_c_buf_p);
1033 | yy_bp = (yytext_ptr) + YY_MORE_ADJ;
1034 | goto yy_find_action;
1035 | }
1036 | break;
1037 | }
1038 |
1039 | default:
1040 | YY_FATAL_ERROR(
1041 | "fatal flex scanner internal error--no action found" );
1042 | } /* end of action switch */
1043 | } /* end of scanning one token */
1044 | } /* end of yylex */
1045 |
1046 | /* yy_get_next_buffer - try to read in a new buffer
1047 | *
1048 | * Returns a code representing an action:
1049 | * EOB_ACT_LAST_MATCH -
1050 | * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
1051 | * EOB_ACT_END_OF_FILE - end of file
1052 | */
1053 | static int yy_get_next_buffer (void)
1054 | {
1055 | register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
1056 | register char *source = (yytext_ptr);
1057 | register int number_to_move, i;
1058 | int ret_val;
1059 |
1060 | if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
1061 | YY_FATAL_ERROR(
1062 | "fatal flex scanner internal error--end of buffer missed" );
1063 |
1064 | if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
1065 | { /* Don't try to fill the buffer, so this is an EOF. */
1066 | if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
1067 | {
1068 | /* We matched a single character, the EOB, so
1069 | * treat this as a final EOF.
1070 | */
1071 | return EOB_ACT_END_OF_FILE;
1072 | }
1073 |
1074 | else
1075 | {
1076 | /* We matched some text prior to the EOB, first
1077 | * process it.
1078 | */
1079 | return EOB_ACT_LAST_MATCH;
1080 | }
1081 | }
1082 |
1083 | /* Try to read more data. */
1084 |
1085 | /* First move last chars to start of buffer. */
1086 | number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
1087 |
1088 | for ( i = 0; i < number_to_move; ++i )
1089 | *(dest++) = *(source++);
1090 |
1091 | if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
1092 | /* don't do the read, it's not guaranteed to return an EOF,
1093 | * just force an EOF
1094 | */
1095 | YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
1096 |
1097 | else
1098 | {
1099 | yy_size_t num_to_read =
1100 | YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
1101 |
1102 | while ( num_to_read <= 0 )
1103 | { /* Not enough room in the buffer - grow it. */
1104 |
1105 | /* just a shorter name for the current buffer */
1106 | YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
1107 |
1108 | int yy_c_buf_p_offset =
1109 | (int) ((yy_c_buf_p) - b->yy_ch_buf);
1110 |
1111 | if ( b->yy_is_our_buffer )
1112 | {
1113 | yy_size_t new_size = b->yy_buf_size * 2;
1114 |
1115 | if ( new_size <= 0 )
1116 | b->yy_buf_size += b->yy_buf_size / 8;
1117 | else
1118 | b->yy_buf_size *= 2;
1119 |
1120 | b->yy_ch_buf = (char *)
1121 | /* Include room in for 2 EOB chars. */
1122 | yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
1123 | }
1124 | else
1125 | /* Can't grow it, we don't own it. */
1126 | b->yy_ch_buf = 0;
1127 |
1128 | if ( ! b->yy_ch_buf )
1129 | YY_FATAL_ERROR(
1130 | "fatal error - scanner input buffer overflow" );
1131 |
1132 | (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
1133 |
1134 | num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
1135 | number_to_move - 1;
1136 |
1137 | }
1138 |
1139 | if ( num_to_read > YY_READ_BUF_SIZE )
1140 | num_to_read = YY_READ_BUF_SIZE;
1141 |
1142 | /* Read in more data. */
1143 | YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
1144 | (yy_n_chars), num_to_read );
1145 |
1146 | YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
1147 | }
1148 |
1149 | if ( (yy_n_chars) == 0 )
1150 | {
1151 | if ( number_to_move == YY_MORE_ADJ )
1152 | {
1153 | ret_val = EOB_ACT_END_OF_FILE;
1154 | yyrestart(yyin );
1155 | }
1156 |
1157 | else
1158 | {
1159 | ret_val = EOB_ACT_LAST_MATCH;
1160 | YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
1161 | YY_BUFFER_EOF_PENDING;
1162 | }
1163 | }
1164 |
1165 | else
1166 | ret_val = EOB_ACT_CONTINUE_SCAN;
1167 |
1168 | if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
1169 | /* Extend the array by 50%, plus the number we really need. */
1170 | yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
1171 | YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
1172 | if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
1173 | YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
1174 | }
1175 |
1176 | (yy_n_chars) += number_to_move;
1177 | YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
1178 | YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
1179 |
1180 | (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
1181 |
1182 | return ret_val;
1183 | }
1184 |
1185 | /* yy_get_previous_state - get the state just before the EOB char was reached */
1186 |
1187 | static yy_state_type yy_get_previous_state (void)
1188 | {
1189 | register yy_state_type yy_current_state;
1190 | register char *yy_cp;
1191 |
1192 | yy_current_state = (yy_start);
1193 |
1194 | for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
1195 | {
1196 | register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
1197 | if ( yy_accept[yy_current_state] )
1198 | {
1199 | (yy_last_accepting_state) = yy_current_state;
1200 | (yy_last_accepting_cpos) = yy_cp;
1201 | }
1202 | while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1203 | {
1204 | yy_current_state = (int) yy_def[yy_current_state];
1205 | if ( yy_current_state >= 67 )
1206 | yy_c = yy_meta[(unsigned int) yy_c];
1207 | }
1208 | yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
1209 | }
1210 |
1211 | return yy_current_state;
1212 | }
1213 |
1214 | /* yy_try_NUL_trans - try to make a transition on the NUL character
1215 | *
1216 | * synopsis
1217 | * next_state = yy_try_NUL_trans( current_state );
1218 | */
1219 | static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
1220 | {
1221 | register int yy_is_jam;
1222 | register char *yy_cp = (yy_c_buf_p);
1223 |
1224 | register YY_CHAR yy_c = 1;
1225 | if ( yy_accept[yy_current_state] )
1226 | {
1227 | (yy_last_accepting_state) = yy_current_state;
1228 | (yy_last_accepting_cpos) = yy_cp;
1229 | }
1230 | while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1231 | {
1232 | yy_current_state = (int) yy_def[yy_current_state];
1233 | if ( yy_current_state >= 67 )
1234 | yy_c = yy_meta[(unsigned int) yy_c];
1235 | }
1236 | yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
1237 | yy_is_jam = (yy_current_state == 66);
1238 |
1239 | return yy_is_jam ? 0 : yy_current_state;
1240 | }
1241 |
1242 | static void yyunput (int c, register char * yy_bp )
1243 | {
1244 | register char *yy_cp;
1245 |
1246 | yy_cp = (yy_c_buf_p);
1247 |
1248 | /* undo effects of setting up yytext */
1249 | *yy_cp = (yy_hold_char);
1250 |
1251 | if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
1252 | { /* need to shift things up to make room */
1253 | /* +2 for EOB chars. */
1254 | register yy_size_t number_to_move = (yy_n_chars) + 2;
1255 | register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
1256 | YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
1257 | register char *source =
1258 | &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
1259 |
1260 | while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
1261 | *--dest = *--source;
1262 |
1263 | yy_cp += (int) (dest - source);
1264 | yy_bp += (int) (dest - source);
1265 | YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
1266 | (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
1267 |
1268 | if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
1269 | YY_FATAL_ERROR( "flex scanner push-back overflow" );
1270 | }
1271 |
1272 | *--yy_cp = (char) c;
1273 |
1274 | (yytext_ptr) = yy_bp;
1275 | (yy_hold_char) = *yy_cp;
1276 | (yy_c_buf_p) = yy_cp;
1277 | }
1278 |
1279 | #ifndef YY_NO_INPUT
1280 | #ifdef __cplusplus
1281 | static int yyinput (void)
1282 | #else
1283 | static int input (void)
1284 | #endif
1285 |
1286 | {
1287 | int c;
1288 |
1289 | *(yy_c_buf_p) = (yy_hold_char);
1290 |
1291 | if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
1292 | {
1293 | /* yy_c_buf_p now points to the character we want to return.
1294 | * If this occurs *before* the EOB characters, then it's a
1295 | * valid NUL; if not, then we've hit the end of the buffer.
1296 | */
1297 | if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
1298 | /* This was really a NUL. */
1299 | *(yy_c_buf_p) = '\0';
1300 |
1301 | else
1302 | { /* need more input */
1303 | yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
1304 | ++(yy_c_buf_p);
1305 |
1306 | switch ( yy_get_next_buffer( ) )
1307 | {
1308 | case EOB_ACT_LAST_MATCH:
1309 | /* This happens because yy_g_n_b()
1310 | * sees that we've accumulated a
1311 | * token and flags that we need to
1312 | * try matching the token before
1313 | * proceeding. But for input(),
1314 | * there's no matching to consider.
1315 | * So convert the EOB_ACT_LAST_MATCH
1316 | * to EOB_ACT_END_OF_FILE.
1317 | */
1318 |
1319 | /* Reset buffer status. */
1320 | yyrestart(yyin );
1321 |
1322 | /*FALLTHROUGH*/
1323 |
1324 | case EOB_ACT_END_OF_FILE:
1325 | {
1326 | if ( yywrap( ) )
1327 | return 0;
1328 |
1329 | if ( ! (yy_did_buffer_switch_on_eof) )
1330 | YY_NEW_FILE;
1331 | #ifdef __cplusplus
1332 | return yyinput();
1333 | #else
1334 | return input();
1335 | #endif
1336 | }
1337 |
1338 | case EOB_ACT_CONTINUE_SCAN:
1339 | (yy_c_buf_p) = (yytext_ptr) + offset;
1340 | break;
1341 | }
1342 | }
1343 | }
1344 |
1345 | c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
1346 | *(yy_c_buf_p) = '\0'; /* preserve yytext */
1347 | (yy_hold_char) = *++(yy_c_buf_p);
1348 |
1349 | return c;
1350 | }
1351 | #endif /* ifndef YY_NO_INPUT */
1352 |
1353 | /** Immediately switch to a different input stream.
1354 | * @param input_file A readable stream.
1355 | *
1356 | * @note This function does not reset the start condition to @c INITIAL .
1357 | */
1358 | void yyrestart (FILE * input_file )
1359 | {
1360 |
1361 | if ( ! YY_CURRENT_BUFFER ){
1362 | yyensure_buffer_stack ();
1363 | YY_CURRENT_BUFFER_LVALUE =
1364 | yy_create_buffer(yyin,YY_BUF_SIZE );
1365 | }
1366 |
1367 | yy_init_buffer(YY_CURRENT_BUFFER,input_file );
1368 | yy_load_buffer_state( );
1369 | }
1370 |
1371 | /** Switch to a different input buffer.
1372 | * @param new_buffer The new input buffer.
1373 | *
1374 | */
1375 | void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
1376 | {
1377 |
1378 | /* TODO. We should be able to replace this entire function body
1379 | * with
1380 | * yypop_buffer_state();
1381 | * yypush_buffer_state(new_buffer);
1382 | */
1383 | yyensure_buffer_stack ();
1384 | if ( YY_CURRENT_BUFFER == new_buffer )
1385 | return;
1386 |
1387 | if ( YY_CURRENT_BUFFER )
1388 | {
1389 | /* Flush out information for old buffer. */
1390 | *(yy_c_buf_p) = (yy_hold_char);
1391 | YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
1392 | YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
1393 | }
1394 |
1395 | YY_CURRENT_BUFFER_LVALUE = new_buffer;
1396 | yy_load_buffer_state( );
1397 |
1398 | /* We don't actually know whether we did this switch during
1399 | * EOF (yywrap()) processing, but the only time this flag
1400 | * is looked at is after yywrap() is called, so it's safe
1401 | * to go ahead and always set it.
1402 | */
1403 | (yy_did_buffer_switch_on_eof) = 1;
1404 | }
1405 |
1406 | static void yy_load_buffer_state (void)
1407 | {
1408 | (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
1409 | (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
1410 | yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
1411 | (yy_hold_char) = *(yy_c_buf_p);
1412 | }
1413 |
1414 | /** Allocate and initialize an input buffer state.
1415 | * @param file A readable stream.
1416 | * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
1417 | *
1418 | * @return the allocated buffer state.
1419 | */
1420 | YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
1421 | {
1422 | YY_BUFFER_STATE b;
1423 |
1424 | b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
1425 | if ( ! b )
1426 | YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
1427 |
1428 | b->yy_buf_size = size;
1429 |
1430 | /* yy_ch_buf has to be 2 characters longer than the size given because
1431 | * we need to put in 2 end-of-buffer characters.
1432 | */
1433 | b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 );
1434 | if ( ! b->yy_ch_buf )
1435 | YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
1436 |
1437 | b->yy_is_our_buffer = 1;
1438 |
1439 | yy_init_buffer(b,file );
1440 |
1441 | return b;
1442 | }
1443 |
1444 | /** Destroy the buffer.
1445 | * @param b a buffer created with yy_create_buffer()
1446 | *
1447 | */
1448 | void yy_delete_buffer (YY_BUFFER_STATE b )
1449 | {
1450 |
1451 | if ( ! b )
1452 | return;
1453 |
1454 | if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
1455 | YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
1456 |
1457 | if ( b->yy_is_our_buffer )
1458 | yyfree((void *) b->yy_ch_buf );
1459 |
1460 | yyfree((void *) b );
1461 | }
1462 |
1463 | #ifndef __cplusplus
1464 | extern int isatty (int );
1465 | #endif /* __cplusplus */
1466 |
1467 | /* Initializes or reinitializes a buffer.
1468 | * This function is sometimes called more than once on the same buffer,
1469 | * such as during a yyrestart() or at EOF.
1470 | */
1471 | static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
1472 |
1473 | {
1474 | int oerrno = errno;
1475 |
1476 | yy_flush_buffer(b );
1477 |
1478 | b->yy_input_file = file;
1479 | b->yy_fill_buffer = 1;
1480 |
1481 | /* If b is the current buffer, then yy_init_buffer was _probably_
1482 | * called from yyrestart() or through yy_get_next_buffer.
1483 | * In that case, we don't want to reset the lineno or column.
1484 | */
1485 | if (b != YY_CURRENT_BUFFER){
1486 | b->yy_bs_lineno = 1;
1487 | b->yy_bs_column = 0;
1488 | }
1489 |
1490 | b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
1491 |
1492 | errno = oerrno;
1493 | }
1494 |
1495 | /** Discard all buffered characters. On the next scan, YY_INPUT will be called.
1496 | * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
1497 | *
1498 | */
1499 | void yy_flush_buffer (YY_BUFFER_STATE b )
1500 | {
1501 | if ( ! b )
1502 | return;
1503 |
1504 | b->yy_n_chars = 0;
1505 |
1506 | /* We always need two end-of-buffer characters. The first causes
1507 | * a transition to the end-of-buffer state. The second causes
1508 | * a jam in that state.
1509 | */
1510 | b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
1511 | b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
1512 |
1513 | b->yy_buf_pos = &b->yy_ch_buf[0];
1514 |
1515 | b->yy_at_bol = 1;
1516 | b->yy_buffer_status = YY_BUFFER_NEW;
1517 |
1518 | if ( b == YY_CURRENT_BUFFER )
1519 | yy_load_buffer_state( );
1520 | }
1521 |
1522 | /** Pushes the new state onto the stack. The new state becomes
1523 | * the current state. This function will allocate the stack
1524 | * if necessary.
1525 | * @param new_buffer The new state.
1526 | *
1527 | */
1528 | void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
1529 | {
1530 | if (new_buffer == NULL)
1531 | return;
1532 |
1533 | yyensure_buffer_stack();
1534 |
1535 | /* This block is copied from yy_switch_to_buffer. */
1536 | if ( YY_CURRENT_BUFFER )
1537 | {
1538 | /* Flush out information for old buffer. */
1539 | *(yy_c_buf_p) = (yy_hold_char);
1540 | YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
1541 | YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
1542 | }
1543 |
1544 | /* Only push if top exists. Otherwise, replace top. */
1545 | if (YY_CURRENT_BUFFER)
1546 | (yy_buffer_stack_top)++;
1547 | YY_CURRENT_BUFFER_LVALUE = new_buffer;
1548 |
1549 | /* copied from yy_switch_to_buffer. */
1550 | yy_load_buffer_state( );
1551 | (yy_did_buffer_switch_on_eof) = 1;
1552 | }
1553 |
1554 | /** Removes and deletes the top of the stack, if present.
1555 | * The next element becomes the new top.
1556 | *
1557 | */
1558 | void yypop_buffer_state (void)
1559 | {
1560 | if (!YY_CURRENT_BUFFER)
1561 | return;
1562 |
1563 | yy_delete_buffer(YY_CURRENT_BUFFER );
1564 | YY_CURRENT_BUFFER_LVALUE = NULL;
1565 | if ((yy_buffer_stack_top) > 0)
1566 | --(yy_buffer_stack_top);
1567 |
1568 | if (YY_CURRENT_BUFFER) {
1569 | yy_load_buffer_state( );
1570 | (yy_did_buffer_switch_on_eof) = 1;
1571 | }
1572 | }
1573 |
1574 | /* Allocates the stack if it does not exist.
1575 | * Guarantees space for at least one push.
1576 | */
1577 | static void yyensure_buffer_stack (void)
1578 | {
1579 | yy_size_t num_to_alloc;
1580 |
1581 | if (!(yy_buffer_stack)) {
1582 |
1583 | /* First allocation is just for 2 elements, since we don't know if this
1584 | * scanner will even need a stack. We use 2 instead of 1 to avoid an
1585 | * immediate realloc on the next call.
1586 | */
1587 | num_to_alloc = 1;
1588 | (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
1589 | (num_to_alloc * sizeof(struct yy_buffer_state*)
1590 | );
1591 | if ( ! (yy_buffer_stack) )
1592 | YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
1593 |
1594 | memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
1595 |
1596 | (yy_buffer_stack_max) = num_to_alloc;
1597 | (yy_buffer_stack_top) = 0;
1598 | return;
1599 | }
1600 |
1601 | if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
1602 |
1603 | /* Increase the buffer to prepare for a possible push. */
1604 | int grow_size = 8 /* arbitrary grow size */;
1605 |
1606 | num_to_alloc = (yy_buffer_stack_max) + grow_size;
1607 | (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
1608 | ((yy_buffer_stack),
1609 | num_to_alloc * sizeof(struct yy_buffer_state*)
1610 | );
1611 | if ( ! (yy_buffer_stack) )
1612 | YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
1613 |
1614 | /* zero only the new slots.*/
1615 | memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
1616 | (yy_buffer_stack_max) = num_to_alloc;
1617 | }
1618 | }
1619 |
1620 | /** Setup the input buffer state to scan directly from a user-specified character buffer.
1621 | * @param base the character buffer
1622 | * @param size the size in bytes of the character buffer
1623 | *
1624 | * @return the newly allocated buffer state object.
1625 | */
1626 | YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
1627 | {
1628 | YY_BUFFER_STATE b;
1629 |
1630 | if ( size < 2 ||
1631 | base[size-2] != YY_END_OF_BUFFER_CHAR ||
1632 | base[size-1] != YY_END_OF_BUFFER_CHAR )
1633 | /* They forgot to leave room for the EOB's. */
1634 | return 0;
1635 |
1636 | b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
1637 | if ( ! b )
1638 | YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
1639 |
1640 | b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
1641 | b->yy_buf_pos = b->yy_ch_buf = base;
1642 | b->yy_is_our_buffer = 0;
1643 | b->yy_input_file = 0;
1644 | b->yy_n_chars = b->yy_buf_size;
1645 | b->yy_is_interactive = 0;
1646 | b->yy_at_bol = 1;
1647 | b->yy_fill_buffer = 0;
1648 | b->yy_buffer_status = YY_BUFFER_NEW;
1649 |
1650 | yy_switch_to_buffer(b );
1651 |
1652 | return b;
1653 | }
1654 |
1655 | /** Setup the input buffer state to scan a string. The next call to yylex() will
1656 | * scan from a @e copy of @a str.
1657 | * @param yystr a NUL-terminated string to scan
1658 | *
1659 | * @return the newly allocated buffer state object.
1660 | * @note If you want to scan bytes that may contain NUL values, then use
1661 | * yy_scan_bytes() instead.
1662 | */
1663 | YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
1664 | {
1665 |
1666 | return yy_scan_bytes(yystr,strlen(yystr) );
1667 | }
1668 |
1669 | /** Setup the input buffer state to scan the given bytes. The next call to yylex() will
1670 | * scan from a @e copy of @a bytes.
1671 | * @param bytes the byte buffer to scan
1672 | * @param len the number of bytes in the buffer pointed to by @a bytes.
1673 | *
1674 | * @return the newly allocated buffer state object.
1675 | */
1676 | YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len )
1677 | {
1678 | YY_BUFFER_STATE b;
1679 | char *buf;
1680 | yy_size_t n, i;
1681 |
1682 | /* Get memory for full buffer, including space for trailing EOB's. */
1683 | n = _yybytes_len + 2;
1684 | buf = (char *) yyalloc(n );
1685 | if ( ! buf )
1686 | YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
1687 |
1688 | for ( i = 0; i < _yybytes_len; ++i )
1689 | buf[i] = yybytes[i];
1690 |
1691 | buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
1692 |
1693 | b = yy_scan_buffer(buf,n );
1694 | if ( ! b )
1695 | YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
1696 |
1697 | /* It's okay to grow etc. this buffer, and we should throw it
1698 | * away when we're done.
1699 | */
1700 | b->yy_is_our_buffer = 1;
1701 |
1702 | return b;
1703 | }
1704 |
1705 | #ifndef YY_EXIT_FAILURE
1706 | #define YY_EXIT_FAILURE 2
1707 | #endif
1708 |
1709 | static void yy_fatal_error (yyconst char* msg )
1710 | {
1711 | (void) fprintf( stderr, "%s\n", msg );
1712 | exit( YY_EXIT_FAILURE );
1713 | }
1714 |
1715 | /* Redefine yyless() so it works in section 3 code. */
1716 |
1717 | #undef yyless
1718 | #define yyless(n) \
1719 | do \
1720 | { \
1721 | /* Undo effects of setting up yytext. */ \
1722 | int yyless_macro_arg = (n); \
1723 | YY_LESS_LINENO(yyless_macro_arg);\
1724 | yytext[yyleng] = (yy_hold_char); \
1725 | (yy_c_buf_p) = yytext + yyless_macro_arg; \
1726 | (yy_hold_char) = *(yy_c_buf_p); \
1727 | *(yy_c_buf_p) = '\0'; \
1728 | yyleng = yyless_macro_arg; \
1729 | } \
1730 | while ( 0 )
1731 |
1732 | /* Accessor methods (get/set functions) to struct members. */
1733 |
1734 | /** Get the current line number.
1735 | *
1736 | */
1737 | int yyget_lineno (void)
1738 | {
1739 |
1740 | return yylineno;
1741 | }
1742 |
1743 | /** Get the input stream.
1744 | *
1745 | */
1746 | FILE *yyget_in (void)
1747 | {
1748 | return yyin;
1749 | }
1750 |
1751 | /** Get the output stream.
1752 | *
1753 | */
1754 | FILE *yyget_out (void)
1755 | {
1756 | return yyout;
1757 | }
1758 |
1759 | /** Get the length of the current token.
1760 | *
1761 | */
1762 | yy_size_t yyget_leng (void)
1763 | {
1764 | return yyleng;
1765 | }
1766 |
1767 | /** Get the current token.
1768 | *
1769 | */
1770 |
1771 | char *yyget_text (void)
1772 | {
1773 | return yytext;
1774 | }
1775 |
1776 | /** Set the current line number.
1777 | * @param line_number
1778 | *
1779 | */
1780 | void yyset_lineno (int line_number )
1781 | {
1782 |
1783 | yylineno = line_number;
1784 | }
1785 |
1786 | /** Set the input stream. This does not discard the current
1787 | * input buffer.
1788 | * @param in_str A readable stream.
1789 | *
1790 | * @see yy_switch_to_buffer
1791 | */
1792 | void yyset_in (FILE * in_str )
1793 | {
1794 | yyin = in_str ;
1795 | }
1796 |
1797 | void yyset_out (FILE * out_str )
1798 | {
1799 | yyout = out_str ;
1800 | }
1801 |
1802 | int yyget_debug (void)
1803 | {
1804 | return yy_flex_debug;
1805 | }
1806 |
1807 | void yyset_debug (int bdebug )
1808 | {
1809 | yy_flex_debug = bdebug ;
1810 | }
1811 |
1812 | static int yy_init_globals (void)
1813 | {
1814 | /* Initialization is the same as for the non-reentrant scanner.
1815 | * This function is called from yylex_destroy(), so don't allocate here.
1816 | */
1817 |
1818 | (yy_buffer_stack) = 0;
1819 | (yy_buffer_stack_top) = 0;
1820 | (yy_buffer_stack_max) = 0;
1821 | (yy_c_buf_p) = (char *) 0;
1822 | (yy_init) = 0;
1823 | (yy_start) = 0;
1824 |
1825 | /* Defined in main.c */
1826 | #ifdef YY_STDINIT
1827 | yyin = stdin;
1828 | yyout = stdout;
1829 | #else
1830 | yyin = (FILE *) 0;
1831 | yyout = (FILE *) 0;
1832 | #endif
1833 |
1834 | /* For future reference: Set errno on error, since we are called by
1835 | * yylex_init()
1836 | */
1837 | return 0;
1838 | }
1839 |
1840 | /* yylex_destroy is for both reentrant and non-reentrant scanners. */
1841 | int yylex_destroy (void)
1842 | {
1843 |
1844 | /* Pop the buffer stack, destroying each element. */
1845 | while(YY_CURRENT_BUFFER){
1846 | yy_delete_buffer(YY_CURRENT_BUFFER );
1847 | YY_CURRENT_BUFFER_LVALUE = NULL;
1848 | yypop_buffer_state();
1849 | }
1850 |
1851 | /* Destroy the stack itself. */
1852 | yyfree((yy_buffer_stack) );
1853 | (yy_buffer_stack) = NULL;
1854 |
1855 | /* Reset the globals. This is important in a non-reentrant scanner so the next time
1856 | * yylex() is called, initialization will occur. */
1857 | yy_init_globals( );
1858 |
1859 | return 0;
1860 | }
1861 |
1862 | /*
1863 | * Internal utility routines.
1864 | */
1865 |
1866 | #ifndef yytext_ptr
1867 | static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
1868 | {
1869 | register int i;
1870 | for ( i = 0; i < n; ++i )
1871 | s1[i] = s2[i];
1872 | }
1873 | #endif
1874 |
1875 | #ifdef YY_NEED_STRLEN
1876 | static int yy_flex_strlen (yyconst char * s )
1877 | {
1878 | register int n;
1879 | for ( n = 0; s[n]; ++n )
1880 | ;
1881 |
1882 | return n;
1883 | }
1884 | #endif
1885 |
1886 | void *yyalloc (yy_size_t size )
1887 | {
1888 | return (void *) malloc( size );
1889 | }
1890 |
1891 | void *yyrealloc (void * ptr, yy_size_t size )
1892 | {
1893 | /* The cast to (char *) in the following accommodates both
1894 | * implementations that use char* generic pointers, and those
1895 | * that use void* generic pointers. It works with the latter
1896 | * because both ANSI C and C++ allow castless assignment from
1897 | * any pointer type to void*, and deal with argument conversions
1898 | * as though doing an assignment.
1899 | */
1900 | return (void *) realloc( (char *) ptr, size );
1901 | }
1902 |
1903 | void yyfree (void * ptr )
1904 | {
1905 | free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
1906 | }
1907 |
1908 | #define YYTABLES_NAME "yytables"
1909 |
1910 | #line 39 "calc.l"
1911 |
1912 |
1913 |
1914 | int yywrap(void) {
1915 | return 1;
1916 | }
1917 |
1918 |
--------------------------------------------------------------------------------
/y.tab.c:
--------------------------------------------------------------------------------
1 | /* A Bison parser, made by GNU Bison 2.3. */
2 |
3 | /* Skeleton implementation for Bison's Yacc-like parsers in C
4 |
5 | Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
6 | Free Software Foundation, Inc.
7 |
8 | This program is free software; you can redistribute it and/or modify
9 | it under the terms of the GNU General Public License as published by
10 | the Free Software Foundation; either version 2, or (at your option)
11 | any later version.
12 |
13 | This program is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with this program; if not, write to the Free Software
20 | Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 | Boston, MA 02110-1301, USA. */
22 |
23 | /* As a special exception, you may create a larger work that contains
24 | part or all of the Bison parser skeleton and distribute that work
25 | under terms of your choice, so long as that work isn't itself a
26 | parser generator using the skeleton or a modified version thereof
27 | as a parser skeleton. Alternatively, if you modify or redistribute
28 | the parser skeleton itself, you may (at your option) remove this
29 | special exception, which will cause the skeleton and the resulting
30 | Bison output files to be licensed under the GNU General Public
31 | License without this special exception.
32 |
33 | This special exception was added by the Free Software Foundation in
34 | version 2.2 of Bison. */
35 |
36 | /* C LALR(1) parser skeleton written by Richard Stallman, by
37 | simplifying the original so-called "semantic" parser. */
38 |
39 | /* All symbols defined below should begin with yy or YY, to avoid
40 | infringing on user name space. This should be done even for local
41 | variables, as they might otherwise be expanded by user macros.
42 | There are some unavoidable exceptions within include files to
43 | define necessary library symbols; they are noted "INFRINGES ON
44 | USER NAME SPACE" below. */
45 |
46 | /* Identify Bison output. */
47 | #define YYBISON 1
48 |
49 | /* Bison version. */
50 | #define YYBISON_VERSION "2.3"
51 |
52 | /* Skeleton name. */
53 | #define YYSKELETON_NAME "yacc.c"
54 |
55 | /* Pure parsers. */
56 | #define YYPURE 0
57 |
58 | /* Using locations. */
59 | #define YYLSP_NEEDED 0
60 |
61 |
62 |
63 | /* Tokens. */
64 | #ifndef YYTOKENTYPE
65 | # define YYTOKENTYPE
66 | /* Put the tokens into the symbol table, so that GDB and other debuggers
67 | know about them. */
68 | enum yytokentype {
69 | NUMBER = 258,
70 | TRUE = 259,
71 | FALSE = 260,
72 | VARIABLE = 261,
73 | WHILE = 262,
74 | IF = 263,
75 | PRINT = 264,
76 | END = 265,
77 | DO = 266,
78 | THEN = 267,
79 | ELSE = 268,
80 | OR = 269,
81 | AND = 270,
82 | NOT = 271,
83 | OVER = 272,
84 | PLUS = 273,
85 | MINUS = 274,
86 | MULTI = 275,
87 | LESS = 276,
88 | BIGGER = 277,
89 | EQUAL = 278,
90 | ASSIGN = 279,
91 | LESSEQ = 280,
92 | BIGEQ = 281,
93 | LAPREN = 282,
94 | COMMA = 283,
95 | RPAREN = 284,
96 | SEMI = 285,
97 | START = 286,
98 | IFX = 287,
99 | NE = 288,
100 | EQ = 289,
101 | LE = 290,
102 | GE = 291,
103 | UMINUS = 292
104 | };
105 | #endif
106 | /* Tokens. */
107 | #define NUMBER 258
108 | #define TRUE 259
109 | #define FALSE 260
110 | #define VARIABLE 261
111 | #define WHILE 262
112 | #define IF 263
113 | #define PRINT 264
114 | #define END 265
115 | #define DO 266
116 | #define THEN 267
117 | #define ELSE 268
118 | #define OR 269
119 | #define AND 270
120 | #define NOT 271
121 | #define OVER 272
122 | #define PLUS 273
123 | #define MINUS 274
124 | #define MULTI 275
125 | #define LESS 276
126 | #define BIGGER 277
127 | #define EQUAL 278
128 | #define ASSIGN 279
129 | #define LESSEQ 280
130 | #define BIGEQ 281
131 | #define LAPREN 282
132 | #define COMMA 283
133 | #define RPAREN 284
134 | #define SEMI 285
135 | #define START 286
136 | #define IFX 287
137 | #define NE 288
138 | #define EQ 289
139 | #define LE 290
140 | #define GE 291
141 | #define UMINUS 292
142 |
143 |
144 |
145 |
146 | /* Copy the first part of user declarations. */
147 | #line 1 "calc.y"
148 |
149 | #include
150 | #include
151 | #include
152 | #include "calc.h"
153 |
154 | /* prototypes */
155 | nodeType *opr(int oper, int nops, ...);
156 | nodeType *id(int i);
157 | nodeType *con(int value);
158 | nodeType *boole(int value);
159 | void freeNode(nodeType *p);
160 | int ex(nodeType *p);
161 | int yylex(void);
162 |
163 | void yyerror(char *s);
164 | int sym[26];
165 |
166 |
167 |
168 | /* Enabling traces. */
169 | #ifndef YYDEBUG
170 | # define YYDEBUG 0
171 | #endif
172 |
173 | /* Enabling verbose error messages. */
174 | #ifdef YYERROR_VERBOSE
175 | # undef YYERROR_VERBOSE
176 | # define YYERROR_VERBOSE 1
177 | #else
178 | # define YYERROR_VERBOSE 0
179 | #endif
180 |
181 | /* Enabling the token table. */
182 | #ifndef YYTOKEN_TABLE
183 | # define YYTOKEN_TABLE 0
184 | #endif
185 |
186 | #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
187 | typedef union YYSTYPE
188 | #line 21 "calc.y"
189 | {
190 | int iValue; /* integer value */
191 | int bValue;
192 | char sIndex; /* symbol table index */
193 | nodeType *nPtr; /* node pointer */
194 | }
195 | /* Line 193 of yacc.c. */
196 | #line 197 "y.tab.c"
197 | YYSTYPE;
198 | # define yystype YYSTYPE /* obsolescent; will be withdrawn */
199 | # define YYSTYPE_IS_DECLARED 1
200 | # define YYSTYPE_IS_TRIVIAL 1
201 | #endif
202 |
203 |
204 |
205 | /* Copy the second part of user declarations. */
206 |
207 |
208 | /* Line 216 of yacc.c. */
209 | #line 210 "y.tab.c"
210 |
211 | #ifdef short
212 | # undef short
213 | #endif
214 |
215 | #ifdef YYTYPE_UINT8
216 | typedef YYTYPE_UINT8 yytype_uint8;
217 | #else
218 | typedef unsigned char yytype_uint8;
219 | #endif
220 |
221 | #ifdef YYTYPE_INT8
222 | typedef YYTYPE_INT8 yytype_int8;
223 | #elif (defined __STDC__ || defined __C99__FUNC__ \
224 | || defined __cplusplus || defined _MSC_VER)
225 | typedef signed char yytype_int8;
226 | #else
227 | typedef short int yytype_int8;
228 | #endif
229 |
230 | #ifdef YYTYPE_UINT16
231 | typedef YYTYPE_UINT16 yytype_uint16;
232 | #else
233 | typedef unsigned short int yytype_uint16;
234 | #endif
235 |
236 | #ifdef YYTYPE_INT16
237 | typedef YYTYPE_INT16 yytype_int16;
238 | #else
239 | typedef short int yytype_int16;
240 | #endif
241 |
242 | #ifndef YYSIZE_T
243 | # ifdef __SIZE_TYPE__
244 | # define YYSIZE_T __SIZE_TYPE__
245 | # elif defined size_t
246 | # define YYSIZE_T size_t
247 | # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
248 | || defined __cplusplus || defined _MSC_VER)
249 | # include /* INFRINGES ON USER NAME SPACE */
250 | # define YYSIZE_T size_t
251 | # else
252 | # define YYSIZE_T unsigned int
253 | # endif
254 | #endif
255 |
256 | #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
257 |
258 | #ifndef YY_
259 | # if defined YYENABLE_NLS && YYENABLE_NLS
260 | # if ENABLE_NLS
261 | # include /* INFRINGES ON USER NAME SPACE */
262 | # define YY_(msgid) dgettext ("bison-runtime", msgid)
263 | # endif
264 | # endif
265 | # ifndef YY_
266 | # define YY_(msgid) msgid
267 | # endif
268 | #endif
269 |
270 | /* Suppress unused-variable warnings by "using" E. */
271 | #if ! defined lint || defined __GNUC__
272 | # define YYUSE(e) ((void) (e))
273 | #else
274 | # define YYUSE(e) /* empty */
275 | #endif
276 |
277 | /* Identity function, used to suppress warnings about constant conditions. */
278 | #ifndef lint
279 | # define YYID(n) (n)
280 | #else
281 | #if (defined __STDC__ || defined __C99__FUNC__ \
282 | || defined __cplusplus || defined _MSC_VER)
283 | static int
284 | YYID (int i)
285 | #else
286 | static int
287 | YYID (i)
288 | int i;
289 | #endif
290 | {
291 | return i;
292 | }
293 | #endif
294 |
295 | #if ! defined yyoverflow || YYERROR_VERBOSE
296 |
297 | /* The parser invokes alloca or malloc; define the necessary symbols. */
298 |
299 | # ifdef YYSTACK_USE_ALLOCA
300 | # if YYSTACK_USE_ALLOCA
301 | # ifdef __GNUC__
302 | # define YYSTACK_ALLOC __builtin_alloca
303 | # elif defined __BUILTIN_VA_ARG_INCR
304 | # include /* INFRINGES ON USER NAME SPACE */
305 | # elif defined _AIX
306 | # define YYSTACK_ALLOC __alloca
307 | # elif defined _MSC_VER
308 | # include /* INFRINGES ON USER NAME SPACE */
309 | # define alloca _alloca
310 | # else
311 | # define YYSTACK_ALLOC alloca
312 | # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
313 | || defined __cplusplus || defined _MSC_VER)
314 | # include /* INFRINGES ON USER NAME SPACE */
315 | # ifndef _STDLIB_H
316 | # define _STDLIB_H 1
317 | # endif
318 | # endif
319 | # endif
320 | # endif
321 | # endif
322 |
323 | # ifdef YYSTACK_ALLOC
324 | /* Pacify GCC's `empty if-body' warning. */
325 | # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
326 | # ifndef YYSTACK_ALLOC_MAXIMUM
327 | /* The OS might guarantee only one guard page at the bottom of the stack,
328 | and a page size can be as small as 4096 bytes. So we cannot safely
329 | invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
330 | to allow for a few compiler-allocated temporary stack slots. */
331 | # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
332 | # endif
333 | # else
334 | # define YYSTACK_ALLOC YYMALLOC
335 | # define YYSTACK_FREE YYFREE
336 | # ifndef YYSTACK_ALLOC_MAXIMUM
337 | # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
338 | # endif
339 | # if (defined __cplusplus && ! defined _STDLIB_H \
340 | && ! ((defined YYMALLOC || defined malloc) \
341 | && (defined YYFREE || defined free)))
342 | # include /* INFRINGES ON USER NAME SPACE */
343 | # ifndef _STDLIB_H
344 | # define _STDLIB_H 1
345 | # endif
346 | # endif
347 | # ifndef YYMALLOC
348 | # define YYMALLOC malloc
349 | # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
350 | || defined __cplusplus || defined _MSC_VER)
351 | void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
352 | # endif
353 | # endif
354 | # ifndef YYFREE
355 | # define YYFREE free
356 | # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
357 | || defined __cplusplus || defined _MSC_VER)
358 | void free (void *); /* INFRINGES ON USER NAME SPACE */
359 | # endif
360 | # endif
361 | # endif
362 | #endif /* ! defined yyoverflow || YYERROR_VERBOSE */
363 |
364 |
365 | #if (! defined yyoverflow \
366 | && (! defined __cplusplus \
367 | || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
368 |
369 | /* A type that is properly aligned for any stack member. */
370 | union yyalloc
371 | {
372 | yytype_int16 yyss;
373 | YYSTYPE yyvs;
374 | };
375 |
376 | /* The size of the maximum gap between one aligned stack and the next. */
377 | # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
378 |
379 | /* The size of an array large to enough to hold all stacks, each with
380 | N elements. */
381 | # define YYSTACK_BYTES(N) \
382 | ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
383 | + YYSTACK_GAP_MAXIMUM)
384 |
385 | /* Copy COUNT objects from FROM to TO. The source and destination do
386 | not overlap. */
387 | # ifndef YYCOPY
388 | # if defined __GNUC__ && 1 < __GNUC__
389 | # define YYCOPY(To, From, Count) \
390 | __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
391 | # else
392 | # define YYCOPY(To, From, Count) \
393 | do \
394 | { \
395 | YYSIZE_T yyi; \
396 | for (yyi = 0; yyi < (Count); yyi++) \
397 | (To)[yyi] = (From)[yyi]; \
398 | } \
399 | while (YYID (0))
400 | # endif
401 | # endif
402 |
403 | /* Relocate STACK from its old location to the new one. The
404 | local variables YYSIZE and YYSTACKSIZE give the old and new number of
405 | elements in the stack, and YYPTR gives the new location of the
406 | stack. Advance YYPTR to a properly aligned location for the next
407 | stack. */
408 | # define YYSTACK_RELOCATE(Stack) \
409 | do \
410 | { \
411 | YYSIZE_T yynewbytes; \
412 | YYCOPY (&yyptr->Stack, Stack, yysize); \
413 | Stack = &yyptr->Stack; \
414 | yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
415 | yyptr += yynewbytes / sizeof (*yyptr); \
416 | } \
417 | while (YYID (0))
418 |
419 | #endif
420 |
421 | /* YYFINAL -- State number of the termination state. */
422 | #define YYFINAL 3
423 | /* YYLAST -- Last index in YYTABLE. */
424 | #define YYLAST 158
425 |
426 | /* YYNTOKENS -- Number of terminals. */
427 | #define YYNTOKENS 38
428 | /* YYNNTS -- Number of nonterminals. */
429 | #define YYNNTS 7
430 | /* YYNRULES -- Number of rules. */
431 | #define YYNRULES 30
432 | /* YYNRULES -- Number of states. */
433 | #define YYNSTATES 60
434 |
435 | /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
436 | #define YYUNDEFTOK 2
437 | #define YYMAXUTOK 292
438 |
439 | #define YYTRANSLATE(YYX) \
440 | ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
441 |
442 | /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
443 | static const yytype_uint8 yytranslate[] =
444 | {
445 | 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
446 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
447 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
448 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
449 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
450 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
451 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
452 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
453 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
454 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
455 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
456 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
457 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
458 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
459 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
460 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
461 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
462 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
463 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
464 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
465 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
466 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
467 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
468 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
469 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
470 | 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
471 | 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
472 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
473 | 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
474 | 35, 36, 37
475 | };
476 |
477 | #if YYDEBUG
478 | /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
479 | YYRHS. */
480 | static const yytype_uint8 yyprhs[] =
481 | {
482 | 0, 0, 3, 5, 8, 9, 13, 17, 22, 27,
483 | 34, 39, 41, 45, 47, 51, 55, 59, 63, 65,
484 | 67, 69, 71, 75, 79, 83, 86, 90, 94, 98,
485 | 102
486 | };
487 |
488 | /* YYRHS -- A `-1'-separated list of the rules' RHS. */
489 | static const yytype_int8 yyrhs[] =
490 | {
491 | 39, 0, -1, 40, -1, 40, 41, -1, -1, 9,
492 | 43, 30, -1, 31, 42, 10, -1, 7, 43, 11,
493 | 41, -1, 8, 43, 12, 41, -1, 8, 43, 12,
494 | 41, 13, 41, -1, 6, 24, 43, 30, -1, 43,
495 | -1, 42, 30, 43, -1, 3, -1, 43, 18, 43,
496 | -1, 43, 19, 43, -1, 43, 20, 43, -1, 43,
497 | 17, 43, -1, 5, -1, 4, -1, 6, -1, 44,
498 | -1, 27, 43, 29, -1, 43, 14, 43, -1, 43,
499 | 15, 43, -1, 16, 43, -1, 43, 21, 43, -1,
500 | 43, 25, 43, -1, 43, 23, 43, -1, 43, 26,
501 | 43, -1, 43, 22, 43, -1
502 | };
503 |
504 | /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
505 | static const yytype_uint8 yyrline[] =
506 | {
507 | 0, 46, 46, 50, 51, 55, 56, 57, 58, 59,
508 | 60, 64, 65, 69, 70, 71, 72, 73, 74, 75,
509 | 76, 77, 78, 79, 80, 81, 85, 86, 87, 88,
510 | 89
511 | };
512 | #endif
513 |
514 | #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
515 | /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
516 | First, the terminals, then, starting at YYNTOKENS, nonterminals. */
517 | static const char *const yytname[] =
518 | {
519 | "$end", "error", "$undefined", "NUMBER", "TRUE", "FALSE", "VARIABLE",
520 | "WHILE", "IF", "PRINT", "END", "DO", "THEN", "ELSE", "OR", "AND", "NOT",
521 | "OVER", "PLUS", "MINUS", "MULTI", "LESS", "BIGGER", "EQUAL", "ASSIGN",
522 | "LESSEQ", "BIGEQ", "LAPREN", "COMMA", "RPAREN", "SEMI", "START", "IFX",
523 | "NE", "EQ", "LE", "GE", "UMINUS", "$accept", "prgmbody", "stmntlist",
524 | "stmnt", "explist", "expitem", "boolreln", 0
525 | };
526 | #endif
527 |
528 | # ifdef YYPRINT
529 | /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
530 | token YYLEX-NUM. */
531 | static const yytype_uint16 yytoknum[] =
532 | {
533 | 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
534 | 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
535 | 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
536 | 285, 286, 287, 288, 289, 290, 291, 292
537 | };
538 | # endif
539 |
540 | /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
541 | static const yytype_uint8 yyr1[] =
542 | {
543 | 0, 38, 39, 40, 40, 41, 41, 41, 41, 41,
544 | 41, 42, 42, 43, 43, 43, 43, 43, 43, 43,
545 | 43, 43, 43, 43, 43, 43, 44, 44, 44, 44,
546 | 44
547 | };
548 |
549 | /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
550 | static const yytype_uint8 yyr2[] =
551 | {
552 | 0, 2, 1, 2, 0, 3, 3, 4, 4, 6,
553 | 4, 1, 3, 1, 3, 3, 3, 3, 1, 1,
554 | 1, 1, 3, 3, 3, 2, 3, 3, 3, 3,
555 | 3
556 | };
557 |
558 | /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
559 | STATE-NUM when YYTABLE doesn't specify something else to do. Zero
560 | means the default is an error. */
561 | static const yytype_uint8 yydefact[] =
562 | {
563 | 4, 0, 2, 1, 0, 0, 0, 0, 0, 3,
564 | 0, 13, 19, 18, 20, 0, 0, 0, 21, 0,
565 | 0, 0, 11, 0, 25, 0, 0, 0, 0, 0,
566 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
567 | 6, 0, 10, 22, 7, 23, 24, 17, 14, 15,
568 | 16, 26, 30, 28, 27, 29, 8, 12, 0, 9
569 | };
570 |
571 | /* YYDEFGOTO[NTERM-NUM]. */
572 | static const yytype_int8 yydefgoto[] =
573 | {
574 | -1, 1, 2, 9, 21, 17, 18
575 | };
576 |
577 | /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
578 | STATE-NUM. */
579 | #define YYPACT_NINF -22
580 | static const yytype_int16 yypact[] =
581 | {
582 | -22, 3, 5, -22, -18, 35, 35, 35, 35, -22,
583 | 35, -22, -22, -22, -22, 35, 35, 77, -22, 106,
584 | 46, 22, 119, 60, 119, 90, 5, 35, 35, 35,
585 | 35, 35, 35, 35, 35, 35, 35, 35, 5, -22,
586 | -22, 35, -22, -22, -22, 119, 119, -7, 132, 132,
587 | -7, 30, 30, 119, 119, 119, 2, 119, 5, -22
588 | };
589 |
590 | /* YYPGOTO[NTERM-NUM]. */
591 | static const yytype_int8 yypgoto[] =
592 | {
593 | -22, -22, -22, -21, -22, -6, -22
594 | };
595 |
596 | /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
597 | positive, shift that token. If negative, reduce the rule which
598 | number is the opposite. If zero, do what YYDEFACT says.
599 | If YYTABLE_NINF, syntax error. */
600 | #define YYTABLE_NINF -1
601 | static const yytype_uint8 yytable[] =
602 | {
603 | 19, 20, 22, 3, 23, 44, 10, 27, 28, 24,
604 | 25, 4, 5, 6, 7, 58, 35, 56, 36, 37,
605 | 0, 45, 46, 47, 48, 49, 50, 51, 52, 53,
606 | 54, 55, 40, 0, 0, 57, 8, 59, 11, 12,
607 | 13, 14, 0, 0, 27, 28, 0, 29, 30, 31,
608 | 32, 15, 41, 35, 0, 36, 37, 0, 0, 0,
609 | 27, 28, 16, 29, 30, 31, 32, 33, 34, 35,
610 | 0, 36, 37, 0, 27, 28, 39, 29, 30, 31,
611 | 32, 33, 34, 35, 0, 36, 37, 0, 26, 0,
612 | 42, 27, 28, 0, 29, 30, 31, 32, 33, 34,
613 | 35, 0, 36, 37, 27, 28, 0, 29, 30, 31,
614 | 32, 33, 34, 35, 0, 36, 37, 0, 38, 43,
615 | 27, 28, 0, 29, 30, 31, 32, 33, 34, 35,
616 | 0, 36, 37, 27, 28, 0, 29, 30, 31, 32,
617 | 33, 34, 35, 0, 36, 37, 27, 28, 0, 29,
618 | 0, 0, 32, 0, 0, 35, 0, 36, 37
619 | };
620 |
621 | static const yytype_int8 yycheck[] =
622 | {
623 | 6, 7, 8, 0, 10, 26, 24, 14, 15, 15,
624 | 16, 6, 7, 8, 9, 13, 23, 38, 25, 26,
625 | -1, 27, 28, 29, 30, 31, 32, 33, 34, 35,
626 | 36, 37, 10, -1, -1, 41, 31, 58, 3, 4,
627 | 5, 6, -1, -1, 14, 15, -1, 17, 18, 19,
628 | 20, 16, 30, 23, -1, 25, 26, -1, -1, -1,
629 | 14, 15, 27, 17, 18, 19, 20, 21, 22, 23,
630 | -1, 25, 26, -1, 14, 15, 30, 17, 18, 19,
631 | 20, 21, 22, 23, -1, 25, 26, -1, 11, -1,
632 | 30, 14, 15, -1, 17, 18, 19, 20, 21, 22,
633 | 23, -1, 25, 26, 14, 15, -1, 17, 18, 19,
634 | 20, 21, 22, 23, -1, 25, 26, -1, 12, 29,
635 | 14, 15, -1, 17, 18, 19, 20, 21, 22, 23,
636 | -1, 25, 26, 14, 15, -1, 17, 18, 19, 20,
637 | 21, 22, 23, -1, 25, 26, 14, 15, -1, 17,
638 | -1, -1, 20, -1, -1, 23, -1, 25, 26
639 | };
640 |
641 | /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
642 | symbol of state STATE-NUM. */
643 | static const yytype_uint8 yystos[] =
644 | {
645 | 0, 39, 40, 0, 6, 7, 8, 9, 31, 41,
646 | 24, 3, 4, 5, 6, 16, 27, 43, 44, 43,
647 | 43, 42, 43, 43, 43, 43, 11, 14, 15, 17,
648 | 18, 19, 20, 21, 22, 23, 25, 26, 12, 30,
649 | 10, 30, 30, 29, 41, 43, 43, 43, 43, 43,
650 | 43, 43, 43, 43, 43, 43, 41, 43, 13, 41
651 | };
652 |
653 | #define yyerrok (yyerrstatus = 0)
654 | #define yyclearin (yychar = YYEMPTY)
655 | #define YYEMPTY (-2)
656 | #define YYEOF 0
657 |
658 | #define YYACCEPT goto yyacceptlab
659 | #define YYABORT goto yyabortlab
660 | #define YYERROR goto yyerrorlab
661 |
662 |
663 | /* Like YYERROR except do call yyerror. This remains here temporarily
664 | to ease the transition to the new meaning of YYERROR, for GCC.
665 | Once GCC version 2 has supplanted version 1, this can go. */
666 |
667 | #define YYFAIL goto yyerrlab
668 |
669 | #define YYRECOVERING() (!!yyerrstatus)
670 |
671 | #define YYBACKUP(Token, Value) \
672 | do \
673 | if (yychar == YYEMPTY && yylen == 1) \
674 | { \
675 | yychar = (Token); \
676 | yylval = (Value); \
677 | yytoken = YYTRANSLATE (yychar); \
678 | YYPOPSTACK (1); \
679 | goto yybackup; \
680 | } \
681 | else \
682 | { \
683 | yyerror (YY_("syntax error: cannot back up")); \
684 | YYERROR; \
685 | } \
686 | while (YYID (0))
687 |
688 |
689 | #define YYTERROR 1
690 | #define YYERRCODE 256
691 |
692 |
693 | /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
694 | If N is 0, then set CURRENT to the empty location which ends
695 | the previous symbol: RHS[0] (always defined). */
696 |
697 | #define YYRHSLOC(Rhs, K) ((Rhs)[K])
698 | #ifndef YYLLOC_DEFAULT
699 | # define YYLLOC_DEFAULT(Current, Rhs, N) \
700 | do \
701 | if (YYID (N)) \
702 | { \
703 | (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
704 | (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
705 | (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
706 | (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
707 | } \
708 | else \
709 | { \
710 | (Current).first_line = (Current).last_line = \
711 | YYRHSLOC (Rhs, 0).last_line; \
712 | (Current).first_column = (Current).last_column = \
713 | YYRHSLOC (Rhs, 0).last_column; \
714 | } \
715 | while (YYID (0))
716 | #endif
717 |
718 |
719 | /* YY_LOCATION_PRINT -- Print the location on the stream.
720 | This macro was not mandated originally: define only if we know
721 | we won't break user code: when these are the locations we know. */
722 |
723 | #ifndef YY_LOCATION_PRINT
724 | # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
725 | # define YY_LOCATION_PRINT(File, Loc) \
726 | fprintf (File, "%d.%d-%d.%d", \
727 | (Loc).first_line, (Loc).first_column, \
728 | (Loc).last_line, (Loc).last_column)
729 | # else
730 | # define YY_LOCATION_PRINT(File, Loc) ((void) 0)
731 | # endif
732 | #endif
733 |
734 |
735 | /* YYLEX -- calling `yylex' with the right arguments. */
736 |
737 | #ifdef YYLEX_PARAM
738 | # define YYLEX yylex (YYLEX_PARAM)
739 | #else
740 | # define YYLEX yylex ()
741 | #endif
742 |
743 | /* Enable debugging if requested. */
744 | #if YYDEBUG
745 |
746 | # ifndef YYFPRINTF
747 | # include /* INFRINGES ON USER NAME SPACE */
748 | # define YYFPRINTF fprintf
749 | # endif
750 |
751 | # define YYDPRINTF(Args) \
752 | do { \
753 | if (yydebug) \
754 | YYFPRINTF Args; \
755 | } while (YYID (0))
756 |
757 | # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
758 | do { \
759 | if (yydebug) \
760 | { \
761 | YYFPRINTF (stderr, "%s ", Title); \
762 | yy_symbol_print (stderr, \
763 | Type, Value); \
764 | YYFPRINTF (stderr, "\n"); \
765 | } \
766 | } while (YYID (0))
767 |
768 |
769 | /*--------------------------------.
770 | | Print this symbol on YYOUTPUT. |
771 | `--------------------------------*/
772 |
773 | /*ARGSUSED*/
774 | #if (defined __STDC__ || defined __C99__FUNC__ \
775 | || defined __cplusplus || defined _MSC_VER)
776 | static void
777 | yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
778 | #else
779 | static void
780 | yy_symbol_value_print (yyoutput, yytype, yyvaluep)
781 | FILE *yyoutput;
782 | int yytype;
783 | YYSTYPE const * const yyvaluep;
784 | #endif
785 | {
786 | if (!yyvaluep)
787 | return;
788 | # ifdef YYPRINT
789 | if (yytype < YYNTOKENS)
790 | YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
791 | # else
792 | YYUSE (yyoutput);
793 | # endif
794 | switch (yytype)
795 | {
796 | default:
797 | break;
798 | }
799 | }
800 |
801 |
802 | /*--------------------------------.
803 | | Print this symbol on YYOUTPUT. |
804 | `--------------------------------*/
805 |
806 | #if (defined __STDC__ || defined __C99__FUNC__ \
807 | || defined __cplusplus || defined _MSC_VER)
808 | static void
809 | yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
810 | #else
811 | static void
812 | yy_symbol_print (yyoutput, yytype, yyvaluep)
813 | FILE *yyoutput;
814 | int yytype;
815 | YYSTYPE const * const yyvaluep;
816 | #endif
817 | {
818 | if (yytype < YYNTOKENS)
819 | YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
820 | else
821 | YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
822 |
823 | yy_symbol_value_print (yyoutput, yytype, yyvaluep);
824 | YYFPRINTF (yyoutput, ")");
825 | }
826 |
827 | /*------------------------------------------------------------------.
828 | | yy_stack_print -- Print the state stack from its BOTTOM up to its |
829 | | TOP (included). |
830 | `------------------------------------------------------------------*/
831 |
832 | #if (defined __STDC__ || defined __C99__FUNC__ \
833 | || defined __cplusplus || defined _MSC_VER)
834 | static void
835 | yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
836 | #else
837 | static void
838 | yy_stack_print (bottom, top)
839 | yytype_int16 *bottom;
840 | yytype_int16 *top;
841 | #endif
842 | {
843 | YYFPRINTF (stderr, "Stack now");
844 | for (; bottom <= top; ++bottom)
845 | YYFPRINTF (stderr, " %d", *bottom);
846 | YYFPRINTF (stderr, "\n");
847 | }
848 |
849 | # define YY_STACK_PRINT(Bottom, Top) \
850 | do { \
851 | if (yydebug) \
852 | yy_stack_print ((Bottom), (Top)); \
853 | } while (YYID (0))
854 |
855 |
856 | /*------------------------------------------------.
857 | | Report that the YYRULE is going to be reduced. |
858 | `------------------------------------------------*/
859 |
860 | #if (defined __STDC__ || defined __C99__FUNC__ \
861 | || defined __cplusplus || defined _MSC_VER)
862 | static void
863 | yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
864 | #else
865 | static void
866 | yy_reduce_print (yyvsp, yyrule)
867 | YYSTYPE *yyvsp;
868 | int yyrule;
869 | #endif
870 | {
871 | int yynrhs = yyr2[yyrule];
872 | int yyi;
873 | unsigned long int yylno = yyrline[yyrule];
874 | YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
875 | yyrule - 1, yylno);
876 | /* The symbols being reduced. */
877 | for (yyi = 0; yyi < yynrhs; yyi++)
878 | {
879 | fprintf (stderr, " $%d = ", yyi + 1);
880 | yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
881 | &(yyvsp[(yyi + 1) - (yynrhs)])
882 | );
883 | fprintf (stderr, "\n");
884 | }
885 | }
886 |
887 | # define YY_REDUCE_PRINT(Rule) \
888 | do { \
889 | if (yydebug) \
890 | yy_reduce_print (yyvsp, Rule); \
891 | } while (YYID (0))
892 |
893 | /* Nonzero means print parse trace. It is left uninitialized so that
894 | multiple parsers can coexist. */
895 | int yydebug;
896 | #else /* !YYDEBUG */
897 | # define YYDPRINTF(Args)
898 | # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
899 | # define YY_STACK_PRINT(Bottom, Top)
900 | # define YY_REDUCE_PRINT(Rule)
901 | #endif /* !YYDEBUG */
902 |
903 |
904 | /* YYINITDEPTH -- initial size of the parser's stacks. */
905 | #ifndef YYINITDEPTH
906 | # define YYINITDEPTH 200
907 | #endif
908 |
909 | /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
910 | if the built-in stack extension method is used).
911 |
912 | Do not make this value too large; the results are undefined if
913 | YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
914 | evaluated with infinite-precision integer arithmetic. */
915 |
916 | #ifndef YYMAXDEPTH
917 | # define YYMAXDEPTH 10000
918 | #endif
919 |
920 |
921 |
922 | #if YYERROR_VERBOSE
923 |
924 | # ifndef yystrlen
925 | # if defined __GLIBC__ && defined _STRING_H
926 | # define yystrlen strlen
927 | # else
928 | /* Return the length of YYSTR. */
929 | #if (defined __STDC__ || defined __C99__FUNC__ \
930 | || defined __cplusplus || defined _MSC_VER)
931 | static YYSIZE_T
932 | yystrlen (const char *yystr)
933 | #else
934 | static YYSIZE_T
935 | yystrlen (yystr)
936 | const char *yystr;
937 | #endif
938 | {
939 | YYSIZE_T yylen;
940 | for (yylen = 0; yystr[yylen]; yylen++)
941 | continue;
942 | return yylen;
943 | }
944 | # endif
945 | # endif
946 |
947 | # ifndef yystpcpy
948 | # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
949 | # define yystpcpy stpcpy
950 | # else
951 | /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
952 | YYDEST. */
953 | #if (defined __STDC__ || defined __C99__FUNC__ \
954 | || defined __cplusplus || defined _MSC_VER)
955 | static char *
956 | yystpcpy (char *yydest, const char *yysrc)
957 | #else
958 | static char *
959 | yystpcpy (yydest, yysrc)
960 | char *yydest;
961 | const char *yysrc;
962 | #endif
963 | {
964 | char *yyd = yydest;
965 | const char *yys = yysrc;
966 |
967 | while ((*yyd++ = *yys++) != '\0')
968 | continue;
969 |
970 | return yyd - 1;
971 | }
972 | # endif
973 | # endif
974 |
975 | # ifndef yytnamerr
976 | /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
977 | quotes and backslashes, so that it's suitable for yyerror. The
978 | heuristic is that double-quoting is unnecessary unless the string
979 | contains an apostrophe, a comma, or backslash (other than
980 | backslash-backslash). YYSTR is taken from yytname. If YYRES is
981 | null, do not copy; instead, return the length of what the result
982 | would have been. */
983 | static YYSIZE_T
984 | yytnamerr (char *yyres, const char *yystr)
985 | {
986 | if (*yystr == '"')
987 | {
988 | YYSIZE_T yyn = 0;
989 | char const *yyp = yystr;
990 |
991 | for (;;)
992 | switch (*++yyp)
993 | {
994 | case '\'':
995 | case ',':
996 | goto do_not_strip_quotes;
997 |
998 | case '\\':
999 | if (*++yyp != '\\')
1000 | goto do_not_strip_quotes;
1001 | /* Fall through. */
1002 | default:
1003 | if (yyres)
1004 | yyres[yyn] = *yyp;
1005 | yyn++;
1006 | break;
1007 |
1008 | case '"':
1009 | if (yyres)
1010 | yyres[yyn] = '\0';
1011 | return yyn;
1012 | }
1013 | do_not_strip_quotes: ;
1014 | }
1015 |
1016 | if (! yyres)
1017 | return yystrlen (yystr);
1018 |
1019 | return yystpcpy (yyres, yystr) - yyres;
1020 | }
1021 | # endif
1022 |
1023 | /* Copy into YYRESULT an error message about the unexpected token
1024 | YYCHAR while in state YYSTATE. Return the number of bytes copied,
1025 | including the terminating null byte. If YYRESULT is null, do not
1026 | copy anything; just return the number of bytes that would be
1027 | copied. As a special case, return 0 if an ordinary "syntax error"
1028 | message will do. Return YYSIZE_MAXIMUM if overflow occurs during
1029 | size calculation. */
1030 | static YYSIZE_T
1031 | yysyntax_error (char *yyresult, int yystate, int yychar)
1032 | {
1033 | int yyn = yypact[yystate];
1034 |
1035 | if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
1036 | return 0;
1037 | else
1038 | {
1039 | int yytype = YYTRANSLATE (yychar);
1040 | YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
1041 | YYSIZE_T yysize = yysize0;
1042 | YYSIZE_T yysize1;
1043 | int yysize_overflow = 0;
1044 | enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
1045 | char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
1046 | int yyx;
1047 |
1048 | # if 0
1049 | /* This is so xgettext sees the translatable formats that are
1050 | constructed on the fly. */
1051 | YY_("syntax error, unexpected %s");
1052 | YY_("syntax error, unexpected %s, expecting %s");
1053 | YY_("syntax error, unexpected %s, expecting %s or %s");
1054 | YY_("syntax error, unexpected %s, expecting %s or %s or %s");
1055 | YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
1056 | # endif
1057 | char *yyfmt;
1058 | char const *yyf;
1059 | static char const yyunexpected[] = "syntax error, unexpected %s";
1060 | static char const yyexpecting[] = ", expecting %s";
1061 | static char const yyor[] = " or %s";
1062 | char yyformat[sizeof yyunexpected
1063 | + sizeof yyexpecting - 1
1064 | + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
1065 | * (sizeof yyor - 1))];
1066 | char const *yyprefix = yyexpecting;
1067 |
1068 | /* Start YYX at -YYN if negative to avoid negative indexes in
1069 | YYCHECK. */
1070 | int yyxbegin = yyn < 0 ? -yyn : 0;
1071 |
1072 | /* Stay within bounds of both yycheck and yytname. */
1073 | int yychecklim = YYLAST - yyn + 1;
1074 | int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1075 | int yycount = 1;
1076 |
1077 | yyarg[0] = yytname[yytype];
1078 | yyfmt = yystpcpy (yyformat, yyunexpected);
1079 |
1080 | for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1081 | if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1082 | {
1083 | if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
1084 | {
1085 | yycount = 1;
1086 | yysize = yysize0;
1087 | yyformat[sizeof yyunexpected - 1] = '\0';
1088 | break;
1089 | }
1090 | yyarg[yycount++] = yytname[yyx];
1091 | yysize1 = yysize + yytnamerr (0, yytname[yyx]);
1092 | yysize_overflow |= (yysize1 < yysize);
1093 | yysize = yysize1;
1094 | yyfmt = yystpcpy (yyfmt, yyprefix);
1095 | yyprefix = yyor;
1096 | }
1097 |
1098 | yyf = YY_(yyformat);
1099 | yysize1 = yysize + yystrlen (yyf);
1100 | yysize_overflow |= (yysize1 < yysize);
1101 | yysize = yysize1;
1102 |
1103 | if (yysize_overflow)
1104 | return YYSIZE_MAXIMUM;
1105 |
1106 | if (yyresult)
1107 | {
1108 | /* Avoid sprintf, as that infringes on the user's name space.
1109 | Don't have undefined behavior even if the translation
1110 | produced a string with the wrong number of "%s"s. */
1111 | char *yyp = yyresult;
1112 | int yyi = 0;
1113 | while ((*yyp = *yyf) != '\0')
1114 | {
1115 | if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
1116 | {
1117 | yyp += yytnamerr (yyp, yyarg[yyi++]);
1118 | yyf += 2;
1119 | }
1120 | else
1121 | {
1122 | yyp++;
1123 | yyf++;
1124 | }
1125 | }
1126 | }
1127 | return yysize;
1128 | }
1129 | }
1130 | #endif /* YYERROR_VERBOSE */
1131 |
1132 |
1133 | /*-----------------------------------------------.
1134 | | Release the memory associated to this symbol. |
1135 | `-----------------------------------------------*/
1136 |
1137 | /*ARGSUSED*/
1138 | #if (defined __STDC__ || defined __C99__FUNC__ \
1139 | || defined __cplusplus || defined _MSC_VER)
1140 | static void
1141 | yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
1142 | #else
1143 | static void
1144 | yydestruct (yymsg, yytype, yyvaluep)
1145 | const char *yymsg;
1146 | int yytype;
1147 | YYSTYPE *yyvaluep;
1148 | #endif
1149 | {
1150 | YYUSE (yyvaluep);
1151 |
1152 | if (!yymsg)
1153 | yymsg = "Deleting";
1154 | YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1155 |
1156 | switch (yytype)
1157 | {
1158 |
1159 | default:
1160 | break;
1161 | }
1162 | }
1163 |
1164 |
1165 | /* Prevent warnings from -Wmissing-prototypes. */
1166 |
1167 | #ifdef YYPARSE_PARAM
1168 | #if defined __STDC__ || defined __cplusplus
1169 | int yyparse (void *YYPARSE_PARAM);
1170 | #else
1171 | int yyparse ();
1172 | #endif
1173 | #else /* ! YYPARSE_PARAM */
1174 | #if defined __STDC__ || defined __cplusplus
1175 | int yyparse (void);
1176 | #else
1177 | int yyparse ();
1178 | #endif
1179 | #endif /* ! YYPARSE_PARAM */
1180 |
1181 |
1182 |
1183 | /* The look-ahead symbol. */
1184 | int yychar;
1185 |
1186 | /* The semantic value of the look-ahead symbol. */
1187 | YYSTYPE yylval;
1188 |
1189 | /* Number of syntax errors so far. */
1190 | int yynerrs;
1191 |
1192 |
1193 |
1194 | /*----------.
1195 | | yyparse. |
1196 | `----------*/
1197 |
1198 | #ifdef YYPARSE_PARAM
1199 | #if (defined __STDC__ || defined __C99__FUNC__ \
1200 | || defined __cplusplus || defined _MSC_VER)
1201 | int
1202 | yyparse (void *YYPARSE_PARAM)
1203 | #else
1204 | int
1205 | yyparse (YYPARSE_PARAM)
1206 | void *YYPARSE_PARAM;
1207 | #endif
1208 | #else /* ! YYPARSE_PARAM */
1209 | #if (defined __STDC__ || defined __C99__FUNC__ \
1210 | || defined __cplusplus || defined _MSC_VER)
1211 | int
1212 | yyparse (void)
1213 | #else
1214 | int
1215 | yyparse ()
1216 |
1217 | #endif
1218 | #endif
1219 | {
1220 |
1221 | int yystate;
1222 | int yyn;
1223 | int yyresult;
1224 | /* Number of tokens to shift before error messages enabled. */
1225 | int yyerrstatus;
1226 | /* Look-ahead token as an internal (translated) token number. */
1227 | int yytoken = 0;
1228 | #if YYERROR_VERBOSE
1229 | /* Buffer for error messages, and its allocated size. */
1230 | char yymsgbuf[128];
1231 | char *yymsg = yymsgbuf;
1232 | YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1233 | #endif
1234 |
1235 | /* Three stacks and their tools:
1236 | `yyss': related to states,
1237 | `yyvs': related to semantic values,
1238 | `yyls': related to locations.
1239 |
1240 | Refer to the stacks thru separate pointers, to allow yyoverflow
1241 | to reallocate them elsewhere. */
1242 |
1243 | /* The state stack. */
1244 | yytype_int16 yyssa[YYINITDEPTH];
1245 | yytype_int16 *yyss = yyssa;
1246 | yytype_int16 *yyssp;
1247 |
1248 | /* The semantic value stack. */
1249 | YYSTYPE yyvsa[YYINITDEPTH];
1250 | YYSTYPE *yyvs = yyvsa;
1251 | YYSTYPE *yyvsp;
1252 |
1253 |
1254 |
1255 | #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1256 |
1257 | YYSIZE_T yystacksize = YYINITDEPTH;
1258 |
1259 | /* The variables used to return semantic value and location from the
1260 | action routines. */
1261 | YYSTYPE yyval;
1262 |
1263 |
1264 | /* The number of symbols on the RHS of the reduced rule.
1265 | Keep to zero when no symbol should be popped. */
1266 | int yylen = 0;
1267 |
1268 | YYDPRINTF ((stderr, "Starting parse\n"));
1269 |
1270 | yystate = 0;
1271 | yyerrstatus = 0;
1272 | yynerrs = 0;
1273 | yychar = YYEMPTY; /* Cause a token to be read. */
1274 |
1275 | /* Initialize stack pointers.
1276 | Waste one element of value and location stack
1277 | so that they stay on the same level as the state stack.
1278 | The wasted elements are never initialized. */
1279 |
1280 | yyssp = yyss;
1281 | yyvsp = yyvs;
1282 |
1283 | goto yysetstate;
1284 |
1285 | /*------------------------------------------------------------.
1286 | | yynewstate -- Push a new state, which is found in yystate. |
1287 | `------------------------------------------------------------*/
1288 | yynewstate:
1289 | /* In all cases, when you get here, the value and location stacks
1290 | have just been pushed. So pushing a state here evens the stacks. */
1291 | yyssp++;
1292 |
1293 | yysetstate:
1294 | *yyssp = yystate;
1295 |
1296 | if (yyss + yystacksize - 1 <= yyssp)
1297 | {
1298 | /* Get the current used size of the three stacks, in elements. */
1299 | YYSIZE_T yysize = yyssp - yyss + 1;
1300 |
1301 | #ifdef yyoverflow
1302 | {
1303 | /* Give user a chance to reallocate the stack. Use copies of
1304 | these so that the &'s don't force the real ones into
1305 | memory. */
1306 | YYSTYPE *yyvs1 = yyvs;
1307 | yytype_int16 *yyss1 = yyss;
1308 |
1309 |
1310 | /* Each stack pointer address is followed by the size of the
1311 | data in use in that stack, in bytes. This used to be a
1312 | conditional around just the two extra args, but that might
1313 | be undefined if yyoverflow is a macro. */
1314 | yyoverflow (YY_("memory exhausted"),
1315 | &yyss1, yysize * sizeof (*yyssp),
1316 | &yyvs1, yysize * sizeof (*yyvsp),
1317 |
1318 | &yystacksize);
1319 |
1320 | yyss = yyss1;
1321 | yyvs = yyvs1;
1322 | }
1323 | #else /* no yyoverflow */
1324 | # ifndef YYSTACK_RELOCATE
1325 | goto yyexhaustedlab;
1326 | # else
1327 | /* Extend the stack our own way. */
1328 | if (YYMAXDEPTH <= yystacksize)
1329 | goto yyexhaustedlab;
1330 | yystacksize *= 2;
1331 | if (YYMAXDEPTH < yystacksize)
1332 | yystacksize = YYMAXDEPTH;
1333 |
1334 | {
1335 | yytype_int16 *yyss1 = yyss;
1336 | union yyalloc *yyptr =
1337 | (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1338 | if (! yyptr)
1339 | goto yyexhaustedlab;
1340 | YYSTACK_RELOCATE (yyss);
1341 | YYSTACK_RELOCATE (yyvs);
1342 |
1343 | # undef YYSTACK_RELOCATE
1344 | if (yyss1 != yyssa)
1345 | YYSTACK_FREE (yyss1);
1346 | }
1347 | # endif
1348 | #endif /* no yyoverflow */
1349 |
1350 | yyssp = yyss + yysize - 1;
1351 | yyvsp = yyvs + yysize - 1;
1352 |
1353 |
1354 | YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1355 | (unsigned long int) yystacksize));
1356 |
1357 | if (yyss + yystacksize - 1 <= yyssp)
1358 | YYABORT;
1359 | }
1360 |
1361 | YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1362 |
1363 | goto yybackup;
1364 |
1365 | /*-----------.
1366 | | yybackup. |
1367 | `-----------*/
1368 | yybackup:
1369 |
1370 | /* Do appropriate processing given the current state. Read a
1371 | look-ahead token if we need one and don't already have one. */
1372 |
1373 | /* First try to decide what to do without reference to look-ahead token. */
1374 | yyn = yypact[yystate];
1375 | if (yyn == YYPACT_NINF)
1376 | goto yydefault;
1377 |
1378 | /* Not known => get a look-ahead token if don't already have one. */
1379 |
1380 | /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
1381 | if (yychar == YYEMPTY)
1382 | {
1383 | YYDPRINTF ((stderr, "Reading a token: "));
1384 | yychar = YYLEX;
1385 | }
1386 |
1387 | if (yychar <= YYEOF)
1388 | {
1389 | yychar = yytoken = YYEOF;
1390 | YYDPRINTF ((stderr, "Now at end of input.\n"));
1391 | }
1392 | else
1393 | {
1394 | yytoken = YYTRANSLATE (yychar);
1395 | YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1396 | }
1397 |
1398 | /* If the proper action on seeing token YYTOKEN is to reduce or to
1399 | detect an error, take that action. */
1400 | yyn += yytoken;
1401 | if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1402 | goto yydefault;
1403 | yyn = yytable[yyn];
1404 | if (yyn <= 0)
1405 | {
1406 | if (yyn == 0 || yyn == YYTABLE_NINF)
1407 | goto yyerrlab;
1408 | yyn = -yyn;
1409 | goto yyreduce;
1410 | }
1411 |
1412 | if (yyn == YYFINAL)
1413 | YYACCEPT;
1414 |
1415 | /* Count tokens shifted since error; after three, turn off error
1416 | status. */
1417 | if (yyerrstatus)
1418 | yyerrstatus--;
1419 |
1420 | /* Shift the look-ahead token. */
1421 | YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1422 |
1423 | /* Discard the shifted token unless it is eof. */
1424 | if (yychar != YYEOF)
1425 | yychar = YYEMPTY;
1426 |
1427 | yystate = yyn;
1428 | *++yyvsp = yylval;
1429 |
1430 | goto yynewstate;
1431 |
1432 |
1433 | /*-----------------------------------------------------------.
1434 | | yydefault -- do the default action for the current state. |
1435 | `-----------------------------------------------------------*/
1436 | yydefault:
1437 | yyn = yydefact[yystate];
1438 | if (yyn == 0)
1439 | goto yyerrlab;
1440 | goto yyreduce;
1441 |
1442 |
1443 | /*-----------------------------.
1444 | | yyreduce -- Do a reduction. |
1445 | `-----------------------------*/
1446 | yyreduce:
1447 | /* yyn is the number of a rule to reduce with. */
1448 | yylen = yyr2[yyn];
1449 |
1450 | /* If YYLEN is nonzero, implement the default value of the action:
1451 | `$$ = $1'.
1452 |
1453 | Otherwise, the following line sets YYVAL to garbage.
1454 | This behavior is undocumented and Bison
1455 | users should not rely upon it. Assigning to YYVAL
1456 | unconditionally makes the parser a bit smaller, and it avoids a
1457 | GCC warning that YYVAL may be used uninitialized. */
1458 | yyval = yyvsp[1-yylen];
1459 |
1460 |
1461 | YY_REDUCE_PRINT (yyn);
1462 | switch (yyn)
1463 | {
1464 | case 2:
1465 | #line 46 "calc.y"
1466 | { exit(0); }
1467 | break;
1468 |
1469 | case 3:
1470 | #line 50 "calc.y"
1471 | { ex((yyvsp[(2) - (2)].nPtr)); freeNode((yyvsp[(2) - (2)].nPtr)); }
1472 | break;
1473 |
1474 | case 5:
1475 | #line 55 "calc.y"
1476 | { (yyval.nPtr) = opr(PRINT, 1, (yyvsp[(2) - (3)].nPtr),SEMI); }
1477 | break;
1478 |
1479 | case 6:
1480 | #line 56 "calc.y"
1481 | { (yyval.nPtr) = (yyvsp[(2) - (3)].nPtr); }
1482 | break;
1483 |
1484 | case 7:
1485 | #line 57 "calc.y"
1486 | { (yyval.nPtr) = opr(WHILE, 2, (yyvsp[(2) - (4)].nPtr), (yyvsp[(4) - (4)].nPtr)); }
1487 | break;
1488 |
1489 | case 8:
1490 | #line 58 "calc.y"
1491 | { (yyval.nPtr) = opr(IF, 2, (yyvsp[(2) - (4)].nPtr), (yyvsp[(4) - (4)].nPtr)); }
1492 | break;
1493 |
1494 | case 9:
1495 | #line 59 "calc.y"
1496 | { (yyval.nPtr) = opr(IF, 3, (yyvsp[(2) - (6)].nPtr), (yyvsp[(4) - (6)].nPtr), (yyvsp[(6) - (6)].nPtr)); }
1497 | break;
1498 |
1499 | case 10:
1500 | #line 60 "calc.y"
1501 | { (yyval.nPtr) = opr(ASSIGN, 2, id((yyvsp[(1) - (4)].sIndex)), (yyvsp[(3) - (4)].nPtr)); }
1502 | break;
1503 |
1504 | case 11:
1505 | #line 64 "calc.y"
1506 | { (yyval.nPtr) = (yyvsp[(1) - (1)].nPtr); }
1507 | break;
1508 |
1509 | case 12:
1510 | #line 65 "calc.y"
1511 | { (yyval.nPtr) = opr(SEMI, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
1512 | break;
1513 |
1514 | case 13:
1515 | #line 69 "calc.y"
1516 | { (yyval.nPtr) = con((yyvsp[(1) - (1)].iValue)); }
1517 | break;
1518 |
1519 | case 14:
1520 | #line 70 "calc.y"
1521 | { (yyval.nPtr) = opr(PLUS, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
1522 | break;
1523 |
1524 | case 15:
1525 | #line 71 "calc.y"
1526 | { (yyval.nPtr) = opr(MINUS, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
1527 | break;
1528 |
1529 | case 16:
1530 | #line 72 "calc.y"
1531 | { (yyval.nPtr) = opr(MULTI, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
1532 | break;
1533 |
1534 | case 17:
1535 | #line 73 "calc.y"
1536 | { (yyval.nPtr) = opr(OVER, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
1537 | break;
1538 |
1539 | case 18:
1540 | #line 74 "calc.y"
1541 | { (yyval.nPtr) = boole((yyvsp[(1) - (1)].bValue)); }
1542 | break;
1543 |
1544 | case 19:
1545 | #line 75 "calc.y"
1546 | { (yyval.nPtr) = boole((yyvsp[(1) - (1)].bValue)); }
1547 | break;
1548 |
1549 | case 20:
1550 | #line 76 "calc.y"
1551 | { (yyval.nPtr) = id((yyvsp[(1) - (1)].sIndex)); }
1552 | break;
1553 |
1554 | case 22:
1555 | #line 78 "calc.y"
1556 | { (yyval.nPtr) = (yyvsp[(2) - (3)].nPtr); }
1557 | break;
1558 |
1559 | case 26:
1560 | #line 85 "calc.y"
1561 | { (yyval.nPtr) = opr(LESS, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
1562 | break;
1563 |
1564 | case 27:
1565 | #line 86 "calc.y"
1566 | { (yyval.nPtr) = opr(LESSEQ, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
1567 | break;
1568 |
1569 | case 28:
1570 | #line 87 "calc.y"
1571 | { (yyval.nPtr) = opr(EQUAL, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
1572 | break;
1573 |
1574 | case 29:
1575 | #line 88 "calc.y"
1576 | { (yyval.nPtr) = opr(BIGEQ, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
1577 | break;
1578 |
1579 | case 30:
1580 | #line 89 "calc.y"
1581 | { (yyval.nPtr) = opr(BIGGER, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
1582 | break;
1583 |
1584 |
1585 | /* Line 1267 of yacc.c. */
1586 | #line 1587 "y.tab.c"
1587 | default: break;
1588 | }
1589 | YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
1590 |
1591 | YYPOPSTACK (yylen);
1592 | yylen = 0;
1593 | YY_STACK_PRINT (yyss, yyssp);
1594 |
1595 | *++yyvsp = yyval;
1596 |
1597 |
1598 | /* Now `shift' the result of the reduction. Determine what state
1599 | that goes to, based on the state we popped back to and the rule
1600 | number reduced by. */
1601 |
1602 | yyn = yyr1[yyn];
1603 |
1604 | yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1605 | if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1606 | yystate = yytable[yystate];
1607 | else
1608 | yystate = yydefgoto[yyn - YYNTOKENS];
1609 |
1610 | goto yynewstate;
1611 |
1612 |
1613 | /*------------------------------------.
1614 | | yyerrlab -- here on detecting error |
1615 | `------------------------------------*/
1616 | yyerrlab:
1617 | /* If not already recovering from an error, report this error. */
1618 | if (!yyerrstatus)
1619 | {
1620 | ++yynerrs;
1621 | #if ! YYERROR_VERBOSE
1622 | yyerror (YY_("syntax error"));
1623 | #else
1624 | {
1625 | YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
1626 | if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
1627 | {
1628 | YYSIZE_T yyalloc = 2 * yysize;
1629 | if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
1630 | yyalloc = YYSTACK_ALLOC_MAXIMUM;
1631 | if (yymsg != yymsgbuf)
1632 | YYSTACK_FREE (yymsg);
1633 | yymsg = (char *) YYSTACK_ALLOC (yyalloc);
1634 | if (yymsg)
1635 | yymsg_alloc = yyalloc;
1636 | else
1637 | {
1638 | yymsg = yymsgbuf;
1639 | yymsg_alloc = sizeof yymsgbuf;
1640 | }
1641 | }
1642 |
1643 | if (0 < yysize && yysize <= yymsg_alloc)
1644 | {
1645 | (void) yysyntax_error (yymsg, yystate, yychar);
1646 | yyerror (yymsg);
1647 | }
1648 | else
1649 | {
1650 | yyerror (YY_("syntax error"));
1651 | if (yysize != 0)
1652 | goto yyexhaustedlab;
1653 | }
1654 | }
1655 | #endif
1656 | }
1657 |
1658 |
1659 |
1660 | if (yyerrstatus == 3)
1661 | {
1662 | /* If just tried and failed to reuse look-ahead token after an
1663 | error, discard it. */
1664 |
1665 | if (yychar <= YYEOF)
1666 | {
1667 | /* Return failure if at end of input. */
1668 | if (yychar == YYEOF)
1669 | YYABORT;
1670 | }
1671 | else
1672 | {
1673 | yydestruct ("Error: discarding",
1674 | yytoken, &yylval);
1675 | yychar = YYEMPTY;
1676 | }
1677 | }
1678 |
1679 | /* Else will try to reuse look-ahead token after shifting the error
1680 | token. */
1681 | goto yyerrlab1;
1682 |
1683 |
1684 | /*---------------------------------------------------.
1685 | | yyerrorlab -- error raised explicitly by YYERROR. |
1686 | `---------------------------------------------------*/
1687 | yyerrorlab:
1688 |
1689 | /* Pacify compilers like GCC when the user code never invokes
1690 | YYERROR and the label yyerrorlab therefore never appears in user
1691 | code. */
1692 | if (/*CONSTCOND*/ 0)
1693 | goto yyerrorlab;
1694 |
1695 | /* Do not reclaim the symbols of the rule which action triggered
1696 | this YYERROR. */
1697 | YYPOPSTACK (yylen);
1698 | yylen = 0;
1699 | YY_STACK_PRINT (yyss, yyssp);
1700 | yystate = *yyssp;
1701 | goto yyerrlab1;
1702 |
1703 |
1704 | /*-------------------------------------------------------------.
1705 | | yyerrlab1 -- common code for both syntax error and YYERROR. |
1706 | `-------------------------------------------------------------*/
1707 | yyerrlab1:
1708 | yyerrstatus = 3; /* Each real token shifted decrements this. */
1709 |
1710 | for (;;)
1711 | {
1712 | yyn = yypact[yystate];
1713 | if (yyn != YYPACT_NINF)
1714 | {
1715 | yyn += YYTERROR;
1716 | if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1717 | {
1718 | yyn = yytable[yyn];
1719 | if (0 < yyn)
1720 | break;
1721 | }
1722 | }
1723 |
1724 | /* Pop the current state because it cannot handle the error token. */
1725 | if (yyssp == yyss)
1726 | YYABORT;
1727 |
1728 |
1729 | yydestruct ("Error: popping",
1730 | yystos[yystate], yyvsp);
1731 | YYPOPSTACK (1);
1732 | yystate = *yyssp;
1733 | YY_STACK_PRINT (yyss, yyssp);
1734 | }
1735 |
1736 | if (yyn == YYFINAL)
1737 | YYACCEPT;
1738 |
1739 | *++yyvsp = yylval;
1740 |
1741 |
1742 | /* Shift the error token. */
1743 | YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
1744 |
1745 | yystate = yyn;
1746 | goto yynewstate;
1747 |
1748 |
1749 | /*-------------------------------------.
1750 | | yyacceptlab -- YYACCEPT comes here. |
1751 | `-------------------------------------*/
1752 | yyacceptlab:
1753 | yyresult = 0;
1754 | goto yyreturn;
1755 |
1756 | /*-----------------------------------.
1757 | | yyabortlab -- YYABORT comes here. |
1758 | `-----------------------------------*/
1759 | yyabortlab:
1760 | yyresult = 1;
1761 | goto yyreturn;
1762 |
1763 | #ifndef yyoverflow
1764 | /*-------------------------------------------------.
1765 | | yyexhaustedlab -- memory exhaustion comes here. |
1766 | `-------------------------------------------------*/
1767 | yyexhaustedlab:
1768 | yyerror (YY_("memory exhausted"));
1769 | yyresult = 2;
1770 | /* Fall through. */
1771 | #endif
1772 |
1773 | yyreturn:
1774 | if (yychar != YYEOF && yychar != YYEMPTY)
1775 | yydestruct ("Cleanup: discarding lookahead",
1776 | yytoken, &yylval);
1777 | /* Do not reclaim the symbols of the rule which action triggered
1778 | this YYABORT or YYACCEPT. */
1779 | YYPOPSTACK (yylen);
1780 | YY_STACK_PRINT (yyss, yyssp);
1781 | while (yyssp != yyss)
1782 | {
1783 | yydestruct ("Cleanup: popping",
1784 | yystos[*yyssp], yyvsp);
1785 | YYPOPSTACK (1);
1786 | }
1787 | #ifndef yyoverflow
1788 | if (yyss != yyssa)
1789 | YYSTACK_FREE (yyss);
1790 | #endif
1791 | #if YYERROR_VERBOSE
1792 | if (yymsg != yymsgbuf)
1793 | YYSTACK_FREE (yymsg);
1794 | #endif
1795 | /* Make sure YYID is used. */
1796 | return YYID (yyresult);
1797 | }
1798 |
1799 |
1800 | #line 92 "calc.y"
1801 |
1802 |
1803 | nodeType *con(int value) {
1804 | nodeType *p;
1805 |
1806 | /* allocate node */
1807 | if ((p = malloc(sizeof(nodeType))) == NULL)
1808 | yyerror("out of memory");
1809 |
1810 | /* copy information */
1811 | p->type = typeCon;
1812 | p->con.value = value;
1813 |
1814 | return p;
1815 | }
1816 |
1817 | nodeType *boole(int boo) {
1818 | nodeType *p;
1819 |
1820 | /* allocate node */
1821 | if ((p = malloc(sizeof(nodeType))) == NULL)
1822 | yyerror("out of memory");
1823 |
1824 | /* copy information */
1825 | p->type = typeBoolean;
1826 | p->boole.boo = boo;
1827 |
1828 | return p;
1829 | }
1830 |
1831 | nodeType *id(int i) {
1832 | nodeType *p;
1833 |
1834 | /* allocate node */
1835 | if ((p = malloc(sizeof(nodeType))) == NULL)
1836 | yyerror("out of memory");
1837 |
1838 | /* copy information */
1839 | p->type = typeId;
1840 | p->id.i = i;
1841 |
1842 | return p;
1843 | }
1844 |
1845 | nodeType *opr(int oper, int nops, ...) {
1846 | va_list ap;
1847 | nodeType *p;
1848 | int i;
1849 |
1850 | /* allocate node, extending op array */
1851 | if ((p = malloc(sizeof(nodeType) + (nops-1) * sizeof(nodeType *))) == NULL)
1852 | yyerror("out of memory");
1853 |
1854 | /* copy information */
1855 | p->type = typeOpr;
1856 | p->opr.oper = oper;
1857 | p->opr.nops = nops;
1858 | va_start(ap, nops);
1859 | for (i = 0; i < nops; i++)
1860 | p->opr.op[i] = va_arg(ap, nodeType*);
1861 | va_end(ap);
1862 | return p;
1863 | }
1864 |
1865 | void freeNode(nodeType *p) {
1866 | int i;
1867 |
1868 | if (!p) return;
1869 | if (p->type == typeOpr) {
1870 | for (i = 0; i < p->opr.nops; i++)
1871 | freeNode(p->opr.op[i]);
1872 | }
1873 | free (p);
1874 | }
1875 |
1876 | void yyerror(char *s) {
1877 | fprintf(stdout, "%s\n", s);
1878 | }
1879 |
1880 | int main(void) {
1881 | yyparse();
1882 | return 0;
1883 | }
1884 |
1885 |
--------------------------------------------------------------------------------
/y.tab.h:
--------------------------------------------------------------------------------
1 | /* A Bison parser, made by GNU Bison 2.3. */
2 |
3 | /* Skeleton interface for Bison's Yacc-like parsers in C
4 |
5 | Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
6 | Free Software Foundation, Inc.
7 |
8 | This program is free software; you can redistribute it and/or modify
9 | it under the terms of the GNU General Public License as published by
10 | the Free Software Foundation; either version 2, or (at your option)
11 | any later version.
12 |
13 | This program is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with this program; if not, write to the Free Software
20 | Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 | Boston, MA 02110-1301, USA. */
22 |
23 | /* As a special exception, you may create a larger work that contains
24 | part or all of the Bison parser skeleton and distribute that work
25 | under terms of your choice, so long as that work isn't itself a
26 | parser generator using the skeleton or a modified version thereof
27 | as a parser skeleton. Alternatively, if you modify or redistribute
28 | the parser skeleton itself, you may (at your option) remove this
29 | special exception, which will cause the skeleton and the resulting
30 | Bison output files to be licensed under the GNU General Public
31 | License without this special exception.
32 |
33 | This special exception was added by the Free Software Foundation in
34 | version 2.2 of Bison. */
35 |
36 | /* Tokens. */
37 | #ifndef YYTOKENTYPE
38 | # define YYTOKENTYPE
39 | /* Put the tokens into the symbol table, so that GDB and other debuggers
40 | know about them. */
41 | enum yytokentype {
42 | NUMBER = 258,
43 | TRUE = 259,
44 | FALSE = 260,
45 | VARIABLE = 261,
46 | WHILE = 262,
47 | IF = 263,
48 | PRINT = 264,
49 | END = 265,
50 | DO = 266,
51 | THEN = 267,
52 | ELSE = 268,
53 | OR = 269,
54 | AND = 270,
55 | NOT = 271,
56 | OVER = 272,
57 | PLUS = 273,
58 | MINUS = 274,
59 | MULTI = 275,
60 | LESS = 276,
61 | BIGGER = 277,
62 | EQUAL = 278,
63 | ASSIGN = 279,
64 | LESSEQ = 280,
65 | BIGEQ = 281,
66 | LAPREN = 282,
67 | COMMA = 283,
68 | RPAREN = 284,
69 | SEMI = 285,
70 | START = 286,
71 | IFX = 287,
72 | NE = 288,
73 | EQ = 289,
74 | LE = 290,
75 | GE = 291,
76 | UMINUS = 292
77 | };
78 | #endif
79 | /* Tokens. */
80 | #define NUMBER 258
81 | #define TRUE 259
82 | #define FALSE 260
83 | #define VARIABLE 261
84 | #define WHILE 262
85 | #define IF 263
86 | #define PRINT 264
87 | #define END 265
88 | #define DO 266
89 | #define THEN 267
90 | #define ELSE 268
91 | #define OR 269
92 | #define AND 270
93 | #define NOT 271
94 | #define OVER 272
95 | #define PLUS 273
96 | #define MINUS 274
97 | #define MULTI 275
98 | #define LESS 276
99 | #define BIGGER 277
100 | #define EQUAL 278
101 | #define ASSIGN 279
102 | #define LESSEQ 280
103 | #define BIGEQ 281
104 | #define LAPREN 282
105 | #define COMMA 283
106 | #define RPAREN 284
107 | #define SEMI 285
108 | #define START 286
109 | #define IFX 287
110 | #define NE 288
111 | #define EQ 289
112 | #define LE 290
113 | #define GE 291
114 | #define UMINUS 292
115 |
116 |
117 |
118 |
119 | #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
120 | typedef union YYSTYPE
121 | #line 21 "calc.y"
122 | {
123 | int iValue; /* integer value */
124 | int bValue;
125 | char sIndex; /* symbol table index */
126 | nodeType *nPtr; /* node pointer */
127 | }
128 | /* Line 1529 of yacc.c. */
129 | #line 130 "y.tab.h"
130 | YYSTYPE;
131 | # define yystype YYSTYPE /* obsolescent; will be withdrawn */
132 | # define YYSTYPE_IS_DECLARED 1
133 | # define YYSTYPE_IS_TRIVIAL 1
134 | #endif
135 |
136 | extern YYSTYPE yylval;
137 |
138 |
--------------------------------------------------------------------------------