├── 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 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 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 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 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 | ![](images/1.png) 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 | ![](images/2.png) 55 | 56 | ## **User Interface design** 57 | 58 | ![](images/3.png) 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 | ![](images/ndfa.png) 121 | 122 | 123 | ## **Derivation tree** 124 | 125 | Sample code: 126 | 127 | **if** 4 < 5 **then** y:=5; **else** y:=6; 128 | 129 | 130 | ![](images/derivation.png) 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 | ![](images/test1.png) 528 | 529 | **2.** 530 | 531 | ![](images/test2.png) 532 | 533 | **3.** 534 | 535 | ![](images/test3.png) 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 | --------------------------------------------------------------------------------