├── source.ect ├── nodes_s1 ├── a.out └── nodes.cc ├── nodes ├── expnode.cpp ├── node.cpp ├── expnode.h ├── node.h ├── floatnode.h ├── integernode.h ├── floatnode.cpp ├── integernode.cpp ├── statementnode.cpp ├── statementnode.h ├── divnode.h ├── multnode.h ├── plusnode.h ├── minusnode.h ├── divnode.cpp ├── multnode.cpp ├── plusnode.cpp ├── minusnode.cpp ├── programnode.cpp ├── programnode.h ├── visitor.h ├── cppvisitor.h ├── llvmvisitor.h ├── visitor.cpp ├── cppvisitor.cpp └── llvmvisitor.cpp ├── README.md ├── scanner.lex ├── main.cpp ├── parser.ypp ├── llvm-begin └── main.cpp ├── parser.tab.hpp ├── scanner.c └── parser.tab.cpp /source.ect: -------------------------------------------------------------------------------- 1 | 3.3 / 1 + 5 * 3.1; 2 | 5 - 6; 3 | -------------------------------------------------------------------------------- /nodes_s1/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evantypanski/ectlang/HEAD/nodes_s1/a.out -------------------------------------------------------------------------------- /nodes/expnode.cpp: -------------------------------------------------------------------------------- 1 | #include "expnode.h" 2 | #include "node.h" 3 | 4 | ExpNode::ExpNode(int line) : 5 | Node(line) {} 6 | -------------------------------------------------------------------------------- /nodes/node.cpp: -------------------------------------------------------------------------------- 1 | #include "node.h" 2 | 3 | Node::Node(int line) : line(line) {} 4 | 5 | int Node::getLine() { 6 | return line; 7 | } 8 | -------------------------------------------------------------------------------- /nodes/expnode.h: -------------------------------------------------------------------------------- 1 | #ifndef EXP_NODE_H 2 | #define EXP_NODE_H 3 | 4 | #include "node.h" 5 | 6 | class ExpNode: public Node { 7 | public: 8 | ExpNode(int line); 9 | }; 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /nodes/node.h: -------------------------------------------------------------------------------- 1 | #ifndef NODE_H 2 | #define NODE_H 3 | 4 | class Node { 5 | public: 6 | Node(int line); 7 | int getLine(); 8 | virtual void accept(class Visitor &v) = 0; 9 | 10 | private: 11 | int line; 12 | }; 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /nodes/floatnode.h: -------------------------------------------------------------------------------- 1 | #ifndef FLOAT_NODE_H 2 | #define FLOAT_NODE_H 3 | 4 | #include "expnode.h" 5 | 6 | class FloatNode: public ExpNode { 7 | public: 8 | FloatNode(int line, float value); 9 | void accept(class Visitor &v); 10 | float getValue(); 11 | 12 | private: 13 | float value; 14 | }; 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /nodes/integernode.h: -------------------------------------------------------------------------------- 1 | #ifndef INTEGER_NODE_H 2 | #define INTEGER_NODE_H 3 | 4 | #include "expnode.h" 5 | 6 | class IntegerNode: public ExpNode { 7 | public: 8 | IntegerNode(int line, int value); 9 | int getValue(); 10 | void accept(class Visitor &v); 11 | 12 | private: 13 | int value; 14 | }; 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Usage (make sure you have `flex`, `bison`, and `g++` installed): 2 | - `bison parser.ypp` 3 | - `flex -o scanner.c scanner.lex` 4 | - `g++ main.cpp parser.tab.cpp nodes/*.cpp $(llvm-config-12 --ldflags --libs) $(llvm-config-12 --cxxflags) -o ectfrontend.out` 5 | - `./ectfrontend.out < source.ect` 6 | - `clang++ test.ll` 7 | - `./a.out` 8 | -------------------------------------------------------------------------------- /nodes/floatnode.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "floatnode.h" 4 | #include "visitor.h" 5 | 6 | FloatNode::FloatNode(int line, float value) : 7 | ExpNode(line), value(value) {} 8 | 9 | float FloatNode::getValue() { 10 | return value; 11 | } 12 | 13 | void FloatNode::accept(Visitor &v) { 14 | v.visit(this); 15 | } 16 | -------------------------------------------------------------------------------- /nodes/integernode.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "integernode.h" 4 | #include "visitor.h" 5 | 6 | IntegerNode::IntegerNode(int line, int value) : 7 | ExpNode(line), value(value) {} 8 | 9 | int IntegerNode::getValue() { 10 | return value; 11 | } 12 | 13 | void IntegerNode::accept(Visitor &v) { 14 | v.visit(this); 15 | } 16 | -------------------------------------------------------------------------------- /nodes/statementnode.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "statementnode.h" 4 | #include "visitor.h" 5 | 6 | StatementNode::StatementNode(int line, ExpNode *exp) : 7 | Node(line), exp(exp) {} 8 | 9 | ExpNode* StatementNode::getExp() { 10 | return exp; 11 | } 12 | 13 | void StatementNode::accept(Visitor &v) { 14 | v.visit(this); 15 | } 16 | -------------------------------------------------------------------------------- /nodes/statementnode.h: -------------------------------------------------------------------------------- 1 | #ifndef STATEMENT_NODE_H 2 | #define STATEMENT_NODE_H 3 | 4 | #include "expnode.h" 5 | #include "node.h" 6 | 7 | class StatementNode: public Node { 8 | public: 9 | StatementNode(int line, ExpNode *exp); 10 | ExpNode* getExp(); 11 | void accept(class Visitor &v); 12 | 13 | private: 14 | ExpNode *exp; 15 | }; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /nodes/divnode.h: -------------------------------------------------------------------------------- 1 | #ifndef DIV_NODE_H 2 | #define DIV_NODE_H 3 | 4 | #include "expnode.h" 5 | 6 | class DivNode: public ExpNode { 7 | public: 8 | DivNode(int line, ExpNode *left, ExpNode *right); 9 | ExpNode* getLeft(); 10 | ExpNode* getRight(); 11 | void accept(class Visitor &v); 12 | 13 | private: 14 | ExpNode *left, *right; 15 | }; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /nodes/multnode.h: -------------------------------------------------------------------------------- 1 | #ifndef MULT_NODE_H 2 | #define MULT_NODE_H 3 | 4 | #include "expnode.h" 5 | 6 | class MultNode: public ExpNode { 7 | public: 8 | MultNode(int line, ExpNode *left, ExpNode *right); 9 | ExpNode* getLeft(); 10 | ExpNode* getRight(); 11 | void accept(class Visitor &v); 12 | 13 | private: 14 | ExpNode *left, *right; 15 | }; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /nodes/plusnode.h: -------------------------------------------------------------------------------- 1 | #ifndef PLUS_NODE_H 2 | #define PLUS_NODE_H 3 | 4 | #include "expnode.h" 5 | 6 | class PlusNode: public ExpNode { 7 | public: 8 | PlusNode(int line, ExpNode *left, ExpNode *right); 9 | ExpNode* getLeft(); 10 | ExpNode* getRight(); 11 | void accept(class Visitor &v); 12 | 13 | private: 14 | ExpNode *left, *right; 15 | }; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /nodes/minusnode.h: -------------------------------------------------------------------------------- 1 | #ifndef MINUS_NODE_H 2 | #define MINUS_NODE_H 3 | 4 | #include "expnode.h" 5 | 6 | class MinusNode: public ExpNode { 7 | public: 8 | MinusNode(int line, ExpNode *left, ExpNode *right); 9 | ExpNode* getLeft(); 10 | ExpNode* getRight(); 11 | void accept(class Visitor &v); 12 | 13 | private: 14 | ExpNode *left, *right; 15 | }; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /nodes/divnode.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "divnode.h" 4 | #include "visitor.h" 5 | 6 | DivNode::DivNode(int line, ExpNode *left, ExpNode *right) : 7 | ExpNode(line), left(left), right(right) {} 8 | 9 | ExpNode* DivNode::getLeft() { 10 | return left; 11 | } 12 | 13 | ExpNode* DivNode::getRight() { 14 | return right; 15 | } 16 | 17 | void DivNode::accept(Visitor &v) { 18 | v.visit(this); 19 | } 20 | -------------------------------------------------------------------------------- /nodes/multnode.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "multnode.h" 4 | #include "visitor.h" 5 | 6 | MultNode::MultNode(int line, ExpNode *left, ExpNode *right) : 7 | ExpNode(line), left(left), right(right) {} 8 | 9 | ExpNode* MultNode::getLeft() { 10 | return left; 11 | } 12 | 13 | ExpNode* MultNode::getRight() { 14 | return right; 15 | } 16 | 17 | void MultNode::accept(Visitor &v) { 18 | v.visit(this); 19 | } 20 | -------------------------------------------------------------------------------- /nodes/plusnode.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "plusnode.h" 4 | #include "visitor.h" 5 | 6 | PlusNode::PlusNode(int line, ExpNode *left, ExpNode *right) : 7 | ExpNode(line), left(left), right(right) {} 8 | 9 | ExpNode* PlusNode::getLeft() { 10 | return left; 11 | } 12 | 13 | ExpNode* PlusNode::getRight() { 14 | return right; 15 | } 16 | 17 | void PlusNode::accept(Visitor &v) { 18 | v.visit(this); 19 | } 20 | -------------------------------------------------------------------------------- /nodes/minusnode.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "minusnode.h" 4 | #include "visitor.h" 5 | 6 | MinusNode::MinusNode(int line, ExpNode *left, ExpNode *right) : 7 | ExpNode(line), left(left), right(right) {} 8 | 9 | ExpNode* MinusNode::getLeft() { 10 | return left; 11 | } 12 | 13 | ExpNode* MinusNode::getRight() { 14 | return right; 15 | } 16 | 17 | void MinusNode::accept(Visitor &v) { 18 | v.visit(this); 19 | } 20 | -------------------------------------------------------------------------------- /nodes/programnode.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "programnode.h" 4 | #include "visitor.h" 5 | 6 | ProgramNode::ProgramNode(int line) : Node(line) {} 7 | 8 | void ProgramNode::addStatement(StatementNode *statement) { 9 | statements.push_back(statement); 10 | } 11 | 12 | std::vector ProgramNode::getStatements() { 13 | return statements; 14 | } 15 | 16 | void ProgramNode::accept(Visitor &v) { 17 | v.visit(this); 18 | } 19 | -------------------------------------------------------------------------------- /nodes/programnode.h: -------------------------------------------------------------------------------- 1 | #ifndef PROGRAM_NODE_H 2 | #define PROGRAM_NODE_H 3 | 4 | #include 5 | 6 | #include "statementnode.h" 7 | 8 | class ProgramNode: public Node { 9 | public: 10 | ProgramNode(int line); 11 | void addStatement(StatementNode *statement); 12 | std::vector getStatements(); 13 | void accept(class Visitor &v); 14 | 15 | private: 16 | std::vector statements; 17 | }; 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /scanner.lex: -------------------------------------------------------------------------------- 1 | %{ 2 | #include "parser.tab.hpp" 3 | extern "C" int yylex(); 4 | %} 5 | %option noyywrap 6 | %option yylineno 7 | 8 | %% 9 | [0-9]+ { yylval.intVal = atoi(yytext); return INTEGER_LITERAL; } 10 | [0-9]+.[0-9]+ { yylval.floatVal = atof(yytext); return FLOAT_LITERAL; } 11 | "+" { return PLUS; } 12 | "-" { return MINUS; } 13 | "*" { return MULT; } 14 | "/" { return DIV; } 15 | ";" { return SEMI; } 16 | [ \t\r\n\f] ; /* ignore whitespace */ 17 | 18 | -------------------------------------------------------------------------------- /nodes/visitor.h: -------------------------------------------------------------------------------- 1 | #ifndef VISITOR_H 2 | #define VISITOR_H 3 | 4 | #include "programnode.h" 5 | #include "statementnode.h" 6 | #include "plusnode.h" 7 | #include "minusnode.h" 8 | #include "multnode.h" 9 | #include "divnode.h" 10 | #include "integernode.h" 11 | #include "floatnode.h" 12 | 13 | class Visitor { 14 | public: 15 | virtual void visit(ProgramNode *node); 16 | virtual void visit(StatementNode *node); 17 | virtual void visit(IntegerNode *node); 18 | virtual void visit(FloatNode *node); 19 | virtual void visit(PlusNode *node); 20 | virtual void visit(MinusNode *node); 21 | virtual void visit(MultNode *node); 22 | virtual void visit(DivNode *node); 23 | }; 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /nodes/cppvisitor.h: -------------------------------------------------------------------------------- 1 | #ifndef CPPVISITOR_H 2 | #define CPPVISITOR_H 3 | 4 | #include 5 | 6 | #include "visitor.h" 7 | #include "programnode.h" 8 | #include "statementnode.h" 9 | #include "plusnode.h" 10 | #include "minusnode.h" 11 | #include "multnode.h" 12 | #include "divnode.h" 13 | #include "integernode.h" 14 | #include "floatnode.h" 15 | 16 | class CPPVisitor : public Visitor { 17 | public: 18 | CPPVisitor(const char *filename); 19 | void visit(ProgramNode *node); 20 | void visit(StatementNode *node); 21 | void visit(IntegerNode *node); 22 | void visit(FloatNode *node); 23 | void visit(PlusNode *node); 24 | void visit(MinusNode *node); 25 | void visit(MultNode *node); 26 | void visit(DivNode *node); 27 | 28 | private: 29 | std::fstream file; 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "llvm/IR/Module.h" 2 | #include "llvm/IR/Function.h" 3 | #include "llvm/Support/raw_ostream.h" 4 | #include "llvm/IR/Module.h" 5 | #include "llvm/IR/PassManager.h" 6 | #include "llvm/IR/CallingConv.h" 7 | #include "llvm/IR/Verifier.h" 8 | #include "llvm/IR/IRPrintingPasses.h" 9 | #include "llvm/IR/IRBuilder.h" 10 | #include "llvm/IR/LegacyPassManager.h" 11 | #include "llvm/IR/BasicBlock.h" 12 | #include "llvm/IR/Constants.h" 13 | #include "llvm/IR/DerivedTypes.h" 14 | #include "llvm/Pass.h" 15 | 16 | #include "nodes/programnode.h" 17 | #include "nodes/llvmvisitor.h" 18 | 19 | extern ProgramNode* program; 20 | extern int yyparse(); 21 | 22 | int main(int argc, char **argv) { 23 | llvm::LLVMContext context; 24 | std::unique_ptr mod; 25 | mod = std::make_unique("ECTLang module", context); 26 | 27 | yyparse(); 28 | llvm::StringRef filename = "test.ll"; 29 | std::error_code ec; 30 | llvm::raw_fd_ostream out(filename, ec); 31 | LLVMVisitor v(out, context, mod); 32 | program->accept(v); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /nodes/llvmvisitor.h: -------------------------------------------------------------------------------- 1 | #ifndef LLVMVISITOR_H 2 | #define LLVMVISITOR_H 3 | 4 | #include 5 | 6 | #include "llvm/IR/IRBuilder.h" 7 | #include "llvm/IR/Module.h" 8 | 9 | #include "visitor.h" 10 | #include "programnode.h" 11 | #include "statementnode.h" 12 | #include "plusnode.h" 13 | #include "minusnode.h" 14 | #include "multnode.h" 15 | #include "divnode.h" 16 | #include "integernode.h" 17 | #include "floatnode.h" 18 | 19 | class LLVMVisitor : public Visitor { 20 | public: 21 | LLVMVisitor(llvm::raw_fd_ostream &out, 22 | llvm::LLVMContext &context, 23 | std::unique_ptr &mod); 24 | void visit(ProgramNode *node); 25 | void visit(StatementNode *node); 26 | void visit(IntegerNode *node); 27 | void visit(FloatNode *node); 28 | void visit(PlusNode *node); 29 | void visit(MinusNode *node); 30 | void visit(MultNode *node); 31 | void visit(DivNode *node); 32 | 33 | private: 34 | llvm::raw_fd_ostream &out; 35 | llvm::LLVMContext &context; 36 | std::unique_ptr &mod; 37 | llvm::IRBuilder<> builder; 38 | 39 | // The "return value" from the previous visit method. 40 | llvm::Value *ret; 41 | bool floatInst; 42 | }; 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /nodes/visitor.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "visitor.h" 4 | 5 | void Visitor::visit(ProgramNode *node) { 6 | std::cout << "Program" << std::endl; 7 | for (auto statement : node->getStatements()) 8 | statement->accept(*this); 9 | } 10 | 11 | void Visitor::visit(StatementNode *node) { 12 | std::cout << "STATEMENT" << std::endl; 13 | node->getExp()->accept(*this); 14 | } 15 | 16 | void Visitor::visit(IntegerNode *node) { 17 | std::cout << node->getValue(); 18 | } 19 | 20 | void Visitor::visit(FloatNode *node) { 21 | std::cout << node->getValue(); 22 | } 23 | 24 | void Visitor::visit(PlusNode *node) { 25 | node->getLeft()->accept(*this); 26 | std::cout << "+"; 27 | node->getRight()->accept(*this); 28 | } 29 | 30 | void Visitor::visit(MinusNode *node) { 31 | node->getLeft()->accept(*this); 32 | std::cout << "-"; 33 | node->getRight()->accept(*this); 34 | } 35 | 36 | void Visitor::visit(MultNode *node) { 37 | node->getLeft()->accept(*this); 38 | std::cout << "*"; 39 | node->getRight()->accept(*this); 40 | } 41 | 42 | void Visitor::visit(DivNode *node) { 43 | node->getLeft()->accept(*this); 44 | std::cout << "/"; 45 | node->getRight()->accept(*this); 46 | } 47 | -------------------------------------------------------------------------------- /nodes_s1/nodes.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Node { 4 | public: 5 | virtual void accept(class Visitor &v) = 0; 6 | }; 7 | 8 | 9 | class IntegerNode: public Node { 10 | public: 11 | IntegerNode(int value); 12 | void accept(Visitor &v); 13 | int value; 14 | }; 15 | 16 | class PlusNode: public Node { 17 | public: 18 | PlusNode(IntegerNode left, IntegerNode right); 19 | void accept(Visitor &v); 20 | IntegerNode left, right; 21 | }; 22 | 23 | class Visitor { 24 | public: 25 | void visit(IntegerNode *node); 26 | void visit(PlusNode *node); 27 | }; 28 | 29 | IntegerNode::IntegerNode(int value) : value(value) {} 30 | 31 | void IntegerNode::accept(Visitor &v) { 32 | v.visit(this); 33 | } 34 | 35 | PlusNode::PlusNode(IntegerNode left, IntegerNode right) : 36 | left(left), right(right) {} 37 | 38 | void PlusNode::accept(Visitor &v) { 39 | v.visit(this); 40 | } 41 | 42 | void Visitor::visit(IntegerNode *node) { 43 | std::cout << node->value; 44 | } 45 | 46 | void Visitor::visit(PlusNode *node) { 47 | node->left.accept(*this); 48 | std::cout << "+"; 49 | node->right.accept(*this); 50 | std::cout << "=" << node->left.value + node->right.value << std::endl; 51 | } 52 | 53 | 54 | int main() { 55 | IntegerNode leftInt(1), rightInt(2); 56 | PlusNode plus(leftInt, rightInt); 57 | Visitor visitor; 58 | plus.accept(visitor); 59 | } 60 | -------------------------------------------------------------------------------- /parser.ypp: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | #include "nodes/node.h" 5 | #include "nodes/minusnode.h" 6 | #include "nodes/plusnode.h" 7 | #include "nodes/multnode.h" 8 | #include "nodes/divnode.h" 9 | #include "nodes/expnode.h" 10 | #include "nodes/integernode.h" 11 | #include "nodes/floatnode.h" 12 | #include "nodes/programnode.h" 13 | #include "nodes/statementnode.h" 14 | #include "scanner.c" 15 | 16 | using namespace std; 17 | extern "C" int yylex(void); 18 | extern int yylineno; 19 | 20 | void yyerror(char *s) { 21 | cerr << s << endl; 22 | } 23 | 24 | ProgramNode *program; 25 | %} 26 | 27 | %union{ 28 | int intVal; 29 | float floatVal; 30 | class Node *node; 31 | class ExpNode *expNode; 32 | class StatementNode *statementNode; 33 | } 34 | 35 | %start program 36 | 37 | %token INTEGER_LITERAL 38 | %token FLOAT_LITERAL 39 | %token SEMI 40 | %type exp 41 | %type statement 42 | %type program 43 | %left PLUS MINUS 44 | %left MULT DIV 45 | 46 | %% 47 | 48 | program: { program = new ProgramNode(yylineno); } 49 | | program statement { assert(program); program->addStatement($2); } 50 | ; 51 | 52 | statement: exp SEMI { $$ = new StatementNode(yylineno, $1); } 53 | ; 54 | 55 | exp: 56 | INTEGER_LITERAL { $$ = new IntegerNode(yylineno, $1); } 57 | | FLOAT_LITERAL { $$ = new FloatNode(yylineno, $1); } 58 | | exp PLUS exp { $$ = new PlusNode(yylineno, $1, $3); } 59 | | exp MINUS exp { $$ = new MinusNode(yylineno, $1, $3); } 60 | | exp MULT exp { $$ = new MultNode(yylineno, $1, $3); } 61 | | exp DIV exp { $$ = new DivNode(yylineno, $1, $3); } 62 | ; 63 | %% 64 | 65 | -------------------------------------------------------------------------------- /nodes/cppvisitor.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "cppvisitor.h" 4 | #include "programnode.h" 5 | #include "statementnode.h" 6 | #include "plusnode.h" 7 | #include "minusnode.h" 8 | #include "multnode.h" 9 | #include "divnode.h" 10 | #include "integernode.h" 11 | #include "floatnode.h" 12 | 13 | CPPVisitor::CPPVisitor(const char *filename) { 14 | // Open the file we are going to write to. 15 | file.open(filename, std::fstream::out); 16 | } 17 | 18 | void CPPVisitor::visit(ProgramNode *node) { 19 | // Write out the information we need to actually run the C program 20 | // This is hardcoded. It shouldn't be in most cases, but education!! 21 | file << "#include \n"; 22 | file << "int main() {\n"; 23 | for (auto statement : node->getStatements()) 24 | statement->accept(*this); 25 | file << "}\n"; 26 | file.close(); 27 | } 28 | 29 | void CPPVisitor::visit(StatementNode *node) { 30 | // We want to print our statements when the generated C++ code is run. 31 | file << "\tstd::cout << "; 32 | node->getExp()->accept(*this); 33 | file << " << std::endl;\n"; 34 | } 35 | 36 | void CPPVisitor::visit(IntegerNode *node) { 37 | // Append the integer to the file. 38 | file << node->getValue(); 39 | } 40 | 41 | void CPPVisitor::visit(FloatNode *node) { 42 | // Append the float to the file. 43 | file << node->getValue(); 44 | } 45 | 46 | void CPPVisitor::visit(PlusNode *node) { 47 | // Append the addition to the file. 48 | node->getLeft()->accept(*this); 49 | file << " + "; 50 | node->getRight()->accept(*this); 51 | } 52 | 53 | void CPPVisitor::visit(MinusNode *node) { 54 | // Append the subtraction to the file. 55 | node->getLeft()->accept(*this); 56 | file << " - "; 57 | node->getRight()->accept(*this); 58 | } 59 | 60 | void CPPVisitor::visit(MultNode *node) { 61 | // Append the multiplication to the file. 62 | node->getLeft()->accept(*this); 63 | file << " * "; 64 | node->getRight()->accept(*this); 65 | } 66 | 67 | void CPPVisitor::visit(DivNode *node) { 68 | // Append the division to the file. 69 | node->getLeft()->accept(*this); 70 | file << " / "; 71 | node->getRight()->accept(*this); 72 | } 73 | -------------------------------------------------------------------------------- /llvm-begin/main.cpp: -------------------------------------------------------------------------------- 1 | #include "llvm/IR/Module.h" 2 | #include "llvm/IR/IRBuilder.h" 3 | 4 | int main() { 5 | llvm::LLVMContext context; 6 | 7 | std::unique_ptr mod; 8 | mod = std::make_unique("ECTLang module", context); 9 | 10 | // Build IR for this block. 11 | llvm::IRBuilder<> builder(context); 12 | 13 | // Function returns void. 14 | llvm::FunctionType *functionReturnType = 15 | llvm::FunctionType::get(llvm::Type::getVoidTy(context), false); 16 | 17 | // Our main function. 18 | llvm::Function *mainFunction = 19 | llvm::Function::Create(functionReturnType, 20 | llvm::Function::ExternalLinkage, 21 | "main", 22 | mod.get()); 23 | 24 | // Now make a basic block inside of mainFunction. 25 | llvm::BasicBlock *body = llvm::BasicBlock::Create(context, "body", mainFunction); 26 | builder.SetInsertPoint(body); 27 | // Make a simple add with two constants. 28 | llvm::Constant *x = llvm::ConstantInt::getSigned(llvm::Type::getInt32Ty(context), 5); 29 | llvm::Constant *y = llvm::ConstantInt::getSigned(llvm::Type::getInt32Ty(context), -6); 30 | //llvm::Constant *x = llvm::ConstantFP::get(llvm::Type::getDoubleTy(context), 5.5); 31 | //llvm::Constant *y = llvm::ConstantFP::get(llvm::Type::getDoubleTy(context), -6.5); 32 | // For if you need to add an int, x, to a float, y. 33 | //llvm::Value *newX = builder.CreateUIToFP(x, llvm::Type::getDoubleTy(context)); 34 | llvm::Value *add = builder.CreateAdd(x, y, "addtest"); 35 | 36 | std::vector params; 37 | // Pointer to int8 would be like char * 38 | params.push_back(llvm::Type::getInt8PtrTy(context)); 39 | 40 | llvm::FunctionType *printfType = 41 | llvm::FunctionType::get(builder.getInt32Ty(), params, /*isVarArg=*/true); 42 | llvm::Function::Create(printfType, llvm::Function::ExternalLinkage, "printf", 43 | mod.get()); 44 | 45 | // Function call arguments 46 | std::vector printArgs; 47 | llvm::Value *formatStr = builder.CreateGlobalStringPtr("%f\n"); 48 | printArgs.push_back(formatStr); 49 | printArgs.push_back(add); 50 | builder.CreateCall(mod->getFunction("printf"), printArgs); 51 | 52 | builder.CreateRetVoid(); 53 | mod->print(llvm::outs(), nullptr); 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /parser.tab.hpp: -------------------------------------------------------------------------------- 1 | /* A Bison parser, made by GNU Bison 3.5.1. */ 2 | 3 | /* Bison interface for Yacc-like parsers in C 4 | 5 | Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, 6 | 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 3 of the License, or 11 | (at your option) 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, see . */ 20 | 21 | /* As a special exception, you may create a larger work that contains 22 | part or all of the Bison parser skeleton and distribute that work 23 | under terms of your choice, so long as that work isn't itself a 24 | parser generator using the skeleton or a modified version thereof 25 | as a parser skeleton. Alternatively, if you modify or redistribute 26 | the parser skeleton itself, you may (at your option) remove this 27 | special exception, which will cause the skeleton and the resulting 28 | Bison output files to be licensed under the GNU General Public 29 | License without this special exception. 30 | 31 | This special exception was added by the Free Software Foundation in 32 | version 2.2 of Bison. */ 33 | 34 | /* Undocumented macros, especially those whose name start with YY_, 35 | are private implementation details. Do not rely on them. */ 36 | 37 | #ifndef YY_YY_PARSER_TAB_HPP_INCLUDED 38 | # define YY_YY_PARSER_TAB_HPP_INCLUDED 39 | /* Debug traces. */ 40 | #ifndef YYDEBUG 41 | # define YYDEBUG 0 42 | #endif 43 | #if YYDEBUG 44 | extern int yydebug; 45 | #endif 46 | 47 | /* Token type. */ 48 | #ifndef YYTOKENTYPE 49 | # define YYTOKENTYPE 50 | enum yytokentype 51 | { 52 | INTEGER_LITERAL = 258, 53 | FLOAT_LITERAL = 259, 54 | SEMI = 260, 55 | PLUS = 261, 56 | MINUS = 262, 57 | MULT = 263, 58 | DIV = 264 59 | }; 60 | #endif 61 | 62 | /* Value type. */ 63 | #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 64 | union YYSTYPE 65 | { 66 | #line 26 "parser.ypp" 67 | 68 | int intVal; 69 | float floatVal; 70 | class Node *node; 71 | class ExpNode *expNode; 72 | class StatementNode *statementNode; 73 | 74 | #line 75 "parser.tab.hpp" 75 | 76 | }; 77 | typedef union YYSTYPE YYSTYPE; 78 | # define YYSTYPE_IS_TRIVIAL 1 79 | # define YYSTYPE_IS_DECLARED 1 80 | #endif 81 | 82 | 83 | extern YYSTYPE yylval; 84 | 85 | int yyparse (void); 86 | 87 | #endif /* !YY_YY_PARSER_TAB_HPP_INCLUDED */ 88 | -------------------------------------------------------------------------------- /nodes/llvmvisitor.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "llvm/IR/Constants.h" 4 | 5 | #include "llvmvisitor.h" 6 | #include "programnode.h" 7 | #include "statementnode.h" 8 | #include "plusnode.h" 9 | #include "minusnode.h" 10 | #include "multnode.h" 11 | #include "divnode.h" 12 | #include "integernode.h" 13 | #include "floatnode.h" 14 | 15 | LLVMVisitor::LLVMVisitor(llvm::raw_fd_ostream &out, 16 | llvm::LLVMContext &context, 17 | std::unique_ptr &mod) : 18 | out(out), context(context), mod(mod), builder(context) { 19 | ret = nullptr; 20 | floatInst = false; 21 | } 22 | 23 | void LLVMVisitor::visit(ProgramNode *node) { 24 | // Function returns void. 25 | llvm::FunctionType *functionReturnType = 26 | llvm::FunctionType::get(llvm::Type::getVoidTy(context), false); 27 | 28 | // Our main function. 29 | llvm::Function *mainFunction = 30 | llvm::Function::Create(functionReturnType, 31 | llvm::Function::ExternalLinkage, 32 | "main", 33 | mod.get()); 34 | 35 | // Now make a basic block inside of mainFunction. 36 | llvm::BasicBlock *body = llvm::BasicBlock::Create(context, "body", mainFunction); 37 | builder.SetInsertPoint(body); 38 | 39 | // Setup printf prototype. 40 | std::vector params; 41 | // Pointer to int8 would be like char * 42 | params.push_back(llvm::Type::getInt8PtrTy(context)); 43 | 44 | llvm::FunctionType *printfType = 45 | llvm::FunctionType::get(builder.getInt32Ty(), params, /*isVarArg=*/true); 46 | llvm::Function::Create(printfType, llvm::Function::ExternalLinkage, "printf", 47 | mod.get()); 48 | 49 | // Visit all of the statements. 50 | for (auto statement : node->getStatements()) 51 | statement->accept(*this); 52 | 53 | // Return 54 | builder.CreateRetVoid(); 55 | 56 | // Print to thi file! 57 | mod->print(out, nullptr); 58 | out.close(); 59 | } 60 | 61 | void LLVMVisitor::visit(StatementNode *node) { 62 | node->getExp()->accept(*this); 63 | 64 | // Call printf with our returned value. 65 | std::vector printArgs; 66 | 67 | // Change the format string depending on if we're dealing with a float or not. 68 | llvm::Value *formatStr; 69 | if (floatInst) { 70 | formatStr = builder.CreateGlobalStringPtr("%f\n"); 71 | } else { 72 | formatStr = builder.CreateGlobalStringPtr("%d\n"); 73 | } 74 | 75 | printArgs.push_back(formatStr); 76 | printArgs.push_back(ret); 77 | builder.CreateCall(mod->getFunction("printf"), printArgs); 78 | 79 | // Reset the float instruction marker. 80 | floatInst = false; 81 | } 82 | 83 | void LLVMVisitor::visit(IntegerNode *node) { 84 | // Return the LLVM int value. 85 | ret = llvm::ConstantInt::getSigned(llvm::Type::getInt32Ty(context), node->getValue()); 86 | } 87 | 88 | void LLVMVisitor::visit(FloatNode *node) { 89 | // Return the LLVM float value. 90 | ret = llvm::ConstantFP::get(llvm::Type::getDoubleTy(context), node->getValue()); 91 | // Mark that we're now dealing with a float. 92 | floatInst = true; 93 | } 94 | 95 | void LLVMVisitor::visit(PlusNode *node) { 96 | // Get the return value from the left side. 97 | node->getLeft()->accept(*this); 98 | llvm::Value *lhs = ret; 99 | 100 | // Get the return value from the right side. 101 | node->getRight()->accept(*this); 102 | llvm::Value *rhs = ret; 103 | 104 | if (floatInst) { 105 | // Promote RHS or LHS if we're dealing with floats and they're not a float. 106 | // (except we use doubles) 107 | if (!lhs->getType()->isDoubleTy()) 108 | lhs = builder.CreateSIToFP(lhs, llvm::Type::getDoubleTy(context)); 109 | if (!rhs->getType()->isDoubleTy()) 110 | rhs = builder.CreateSIToFP(rhs, llvm::Type::getDoubleTy(context)); 111 | 112 | ret = builder.CreateFAdd(lhs, rhs); 113 | } else { 114 | // Otherwise we're just doing an integer add. 115 | ret = builder.CreateAdd(lhs, rhs); 116 | } 117 | } 118 | 119 | void LLVMVisitor::visit(MinusNode *node) { 120 | // Get the return value from the left side. 121 | node->getLeft()->accept(*this); 122 | llvm::Value *lhs = ret; 123 | 124 | // Get the return value from the right side. 125 | node->getRight()->accept(*this); 126 | llvm::Value *rhs = ret; 127 | 128 | if (floatInst) { 129 | // Promote RHS or LHS if we're dealing with floats and they're not a float. 130 | // (except we use doubles) 131 | if (!lhs->getType()->isDoubleTy()) 132 | lhs = builder.CreateSIToFP(lhs, llvm::Type::getDoubleTy(context)); 133 | if (!rhs->getType()->isDoubleTy()) 134 | rhs = builder.CreateSIToFP(rhs, llvm::Type::getDoubleTy(context)); 135 | 136 | ret = builder.CreateFSub(lhs, rhs); 137 | } else { 138 | // Otherwise we're just doing an integer add. 139 | ret = builder.CreateSub(lhs, rhs); 140 | } 141 | } 142 | 143 | void LLVMVisitor::visit(MultNode *node) { 144 | // Get the return value from the left side. 145 | node->getLeft()->accept(*this); 146 | llvm::Value *lhs = ret; 147 | 148 | // Get the return value from the right side. 149 | node->getRight()->accept(*this); 150 | llvm::Value *rhs = ret; 151 | 152 | if (floatInst) { 153 | // Promote RHS or LHS if we're dealing with floats and they're not a float. 154 | // (except we use doubles) 155 | if (!lhs->getType()->isDoubleTy()) 156 | lhs = builder.CreateSIToFP(lhs, llvm::Type::getDoubleTy(context)); 157 | if (!rhs->getType()->isDoubleTy()) 158 | rhs = builder.CreateSIToFP(rhs, llvm::Type::getDoubleTy(context)); 159 | 160 | ret = builder.CreateFMul(lhs, rhs); 161 | } else { 162 | // Otherwise we're just doing an integer add. 163 | ret = builder.CreateMul(lhs, rhs); 164 | } 165 | } 166 | 167 | void LLVMVisitor::visit(DivNode *node) { 168 | // Get the return value from the left side. 169 | node->getLeft()->accept(*this); 170 | llvm::Value *lhs = ret; 171 | 172 | // Get the return value from the right side. 173 | node->getRight()->accept(*this); 174 | llvm::Value *rhs = ret; 175 | 176 | if (floatInst) { 177 | // Promote RHS or LHS if we're dealing with floats and they're not a float. 178 | // (except we use doubles) 179 | if (!lhs->getType()->isDoubleTy()) 180 | lhs = builder.CreateSIToFP(lhs, llvm::Type::getDoubleTy(context)); 181 | if (!rhs->getType()->isDoubleTy()) 182 | rhs = builder.CreateSIToFP(rhs, llvm::Type::getDoubleTy(context)); 183 | 184 | ret = builder.CreateFDiv(lhs, rhs); 185 | } else { 186 | // Otherwise we're just doing an integer add. 187 | ret = builder.CreateSDiv(lhs, rhs); 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /scanner.c: -------------------------------------------------------------------------------- 1 | #line 2 "scanner.c" 2 | 3 | #line 4 "scanner.c" 4 | 5 | #define YY_INT_ALIGNED short int 6 | 7 | /* A lexical scanner generated by flex */ 8 | 9 | #define FLEX_SCANNER 10 | #define YY_FLEX_MAJOR_VERSION 2 11 | #define YY_FLEX_MINOR_VERSION 6 12 | #define YY_FLEX_SUBMINOR_VERSION 4 13 | #if YY_FLEX_SUBMINOR_VERSION > 0 14 | #define FLEX_BETA 15 | #endif 16 | 17 | /* First, we deal with platform-specific or compiler-specific issues. */ 18 | 19 | /* begin standard C headers. */ 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | /* end standard C headers. */ 26 | 27 | /* flex integer type definitions */ 28 | 29 | #ifndef FLEXINT_H 30 | #define FLEXINT_H 31 | 32 | /* C99 systems have . Non-C99 systems may or may not. */ 33 | 34 | #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 35 | 36 | /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, 37 | * if you want the limit (max/min) macros for int types. 38 | */ 39 | #ifndef __STDC_LIMIT_MACROS 40 | #define __STDC_LIMIT_MACROS 1 41 | #endif 42 | 43 | #include 44 | typedef int8_t flex_int8_t; 45 | typedef uint8_t flex_uint8_t; 46 | typedef int16_t flex_int16_t; 47 | typedef uint16_t flex_uint16_t; 48 | typedef int32_t flex_int32_t; 49 | typedef uint32_t flex_uint32_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 | 58 | /* Limits of integral types. */ 59 | #ifndef INT8_MIN 60 | #define INT8_MIN (-128) 61 | #endif 62 | #ifndef INT16_MIN 63 | #define INT16_MIN (-32767-1) 64 | #endif 65 | #ifndef INT32_MIN 66 | #define INT32_MIN (-2147483647-1) 67 | #endif 68 | #ifndef INT8_MAX 69 | #define INT8_MAX (127) 70 | #endif 71 | #ifndef INT16_MAX 72 | #define INT16_MAX (32767) 73 | #endif 74 | #ifndef INT32_MAX 75 | #define INT32_MAX (2147483647) 76 | #endif 77 | #ifndef UINT8_MAX 78 | #define UINT8_MAX (255U) 79 | #endif 80 | #ifndef UINT16_MAX 81 | #define UINT16_MAX (65535U) 82 | #endif 83 | #ifndef UINT32_MAX 84 | #define UINT32_MAX (4294967295U) 85 | #endif 86 | 87 | #ifndef SIZE_MAX 88 | #define SIZE_MAX (~(size_t)0) 89 | #endif 90 | 91 | #endif /* ! C99 */ 92 | 93 | #endif /* ! FLEXINT_H */ 94 | 95 | /* begin standard C++ headers. */ 96 | 97 | /* TODO: this is always defined, so inline it */ 98 | #define yyconst const 99 | 100 | #if defined(__GNUC__) && __GNUC__ >= 3 101 | #define yynoreturn __attribute__((__noreturn__)) 102 | #else 103 | #define yynoreturn 104 | #endif 105 | 106 | /* Returned upon end-of-file. */ 107 | #define YY_NULL 0 108 | 109 | /* Promotes a possibly negative, possibly signed char to an 110 | * integer in range [0..255] for use as an array index. 111 | */ 112 | #define YY_SC_TO_UI(c) ((YY_CHAR) (c)) 113 | 114 | /* Enter a start condition. This macro really ought to take a parameter, 115 | * but we do it the disgusting crufty way forced on us by the ()-less 116 | * definition of BEGIN. 117 | */ 118 | #define BEGIN (yy_start) = 1 + 2 * 119 | /* Translate the current start state into a value that can be later handed 120 | * to BEGIN to return to the state. The YYSTATE alias is for lex 121 | * compatibility. 122 | */ 123 | #define YY_START (((yy_start) - 1) / 2) 124 | #define YYSTATE YY_START 125 | /* Action number for EOF rule of a given start state. */ 126 | #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) 127 | /* Special action meaning "start processing a new file". */ 128 | #define YY_NEW_FILE yyrestart( yyin ) 129 | #define YY_END_OF_BUFFER_CHAR 0 130 | 131 | /* Size of default input buffer. */ 132 | #ifndef YY_BUF_SIZE 133 | #ifdef __ia64__ 134 | /* On IA-64, the buffer size is 16k, not 8k. 135 | * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. 136 | * Ditto for the __ia64__ case accordingly. 137 | */ 138 | #define YY_BUF_SIZE 32768 139 | #else 140 | #define YY_BUF_SIZE 16384 141 | #endif /* __ia64__ */ 142 | #endif 143 | 144 | /* The state buf must be large enough to hold one state per character in the main buffer. 145 | */ 146 | #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) 147 | 148 | #ifndef YY_TYPEDEF_YY_BUFFER_STATE 149 | #define YY_TYPEDEF_YY_BUFFER_STATE 150 | typedef struct yy_buffer_state *YY_BUFFER_STATE; 151 | #endif 152 | 153 | #ifndef YY_TYPEDEF_YY_SIZE_T 154 | #define YY_TYPEDEF_YY_SIZE_T 155 | typedef size_t yy_size_t; 156 | #endif 157 | 158 | extern int yyleng; 159 | 160 | extern FILE *yyin, *yyout; 161 | 162 | #define EOB_ACT_CONTINUE_SCAN 0 163 | #define EOB_ACT_END_OF_FILE 1 164 | #define EOB_ACT_LAST_MATCH 2 165 | 166 | /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires 167 | * access to the local variable yy_act. Since yyless() is a macro, it would break 168 | * existing scanners that call yyless() from OUTSIDE yylex. 169 | * One obvious solution it to make yy_act a global. I tried that, and saw 170 | * a 5% performance hit in a non-yylineno scanner, because yy_act is 171 | * normally declared as a register variable-- so it is not worth it. 172 | */ 173 | #define YY_LESS_LINENO(n) \ 174 | do { \ 175 | int yyl;\ 176 | for ( yyl = n; yyl < yyleng; ++yyl )\ 177 | if ( yytext[yyl] == '\n' )\ 178 | --yylineno;\ 179 | }while(0) 180 | #define YY_LINENO_REWIND_TO(dst) \ 181 | do {\ 182 | const char *p;\ 183 | for ( p = yy_cp-1; p >= (dst); --p)\ 184 | if ( *p == '\n' )\ 185 | --yylineno;\ 186 | }while(0) 187 | 188 | /* Return all but the first "n" matched characters back to the input stream. */ 189 | #define yyless(n) \ 190 | do \ 191 | { \ 192 | /* Undo effects of setting up yytext. */ \ 193 | int yyless_macro_arg = (n); \ 194 | YY_LESS_LINENO(yyless_macro_arg);\ 195 | *yy_cp = (yy_hold_char); \ 196 | YY_RESTORE_YY_MORE_OFFSET \ 197 | (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ 198 | YY_DO_BEFORE_ACTION; /* set up yytext again */ \ 199 | } \ 200 | while ( 0 ) 201 | #define unput(c) yyunput( c, (yytext_ptr) ) 202 | 203 | #ifndef YY_STRUCT_YY_BUFFER_STATE 204 | #define YY_STRUCT_YY_BUFFER_STATE 205 | struct yy_buffer_state 206 | { 207 | FILE *yy_input_file; 208 | 209 | char *yy_ch_buf; /* input buffer */ 210 | char *yy_buf_pos; /* current position in input buffer */ 211 | 212 | /* Size of input buffer in bytes, not including room for EOB 213 | * characters. 214 | */ 215 | int yy_buf_size; 216 | 217 | /* Number of characters read into yy_ch_buf, not including EOB 218 | * characters. 219 | */ 220 | int yy_n_chars; 221 | 222 | /* Whether we "own" the buffer - i.e., we know we created it, 223 | * and can realloc() it to grow it, and should free() it to 224 | * delete it. 225 | */ 226 | int yy_is_our_buffer; 227 | 228 | /* Whether this is an "interactive" input source; if so, and 229 | * if we're using stdio for input, then we want to use getc() 230 | * instead of fread(), to make sure we stop fetching input after 231 | * each newline. 232 | */ 233 | int yy_is_interactive; 234 | 235 | /* Whether we're considered to be at the beginning of a line. 236 | * If so, '^' rules will be active on the next match, otherwise 237 | * not. 238 | */ 239 | int yy_at_bol; 240 | 241 | int yy_bs_lineno; /**< The line count. */ 242 | int yy_bs_column; /**< The column count. */ 243 | 244 | /* Whether to try to fill the input buffer when we reach the 245 | * end of it. 246 | */ 247 | int yy_fill_buffer; 248 | 249 | int yy_buffer_status; 250 | 251 | #define YY_BUFFER_NEW 0 252 | #define YY_BUFFER_NORMAL 1 253 | /* When an EOF's been seen but there's still some text to process 254 | * then we mark the buffer as YY_EOF_PENDING, to indicate that we 255 | * shouldn't try reading from the input source any more. We might 256 | * still have a bunch of tokens to match, though, because of 257 | * possible backing-up. 258 | * 259 | * When we actually see the EOF, we change the status to "new" 260 | * (via yyrestart()), so that the user can continue scanning by 261 | * just pointing yyin at a new input file. 262 | */ 263 | #define YY_BUFFER_EOF_PENDING 2 264 | 265 | }; 266 | #endif /* !YY_STRUCT_YY_BUFFER_STATE */ 267 | 268 | /* Stack of input buffers. */ 269 | static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ 270 | static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ 271 | static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ 272 | 273 | /* We provide macros for accessing buffer states in case in the 274 | * future we want to put the buffer states in a more general 275 | * "scanner state". 276 | * 277 | * Returns the top of the stack, or NULL. 278 | */ 279 | #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ 280 | ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ 281 | : NULL) 282 | /* Same as previous macro, but useful when we know that the buffer stack is not 283 | * NULL or when we need an lvalue. For internal use only. 284 | */ 285 | #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] 286 | 287 | /* yy_hold_char holds the character lost when yytext is formed. */ 288 | static char yy_hold_char; 289 | static int yy_n_chars; /* number of characters read into yy_ch_buf */ 290 | int yyleng; 291 | 292 | /* Points to current character in buffer. */ 293 | static char *yy_c_buf_p = NULL; 294 | static int yy_init = 0; /* whether we need to initialize */ 295 | static int yy_start = 0; /* start state number */ 296 | 297 | /* Flag which is used to allow yywrap()'s to do buffer switches 298 | * instead of setting up a fresh yyin. A bit of a hack ... 299 | */ 300 | static int yy_did_buffer_switch_on_eof; 301 | 302 | void yyrestart ( FILE *input_file ); 303 | void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); 304 | YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); 305 | void yy_delete_buffer ( YY_BUFFER_STATE b ); 306 | void yy_flush_buffer ( YY_BUFFER_STATE b ); 307 | void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); 308 | void yypop_buffer_state ( void ); 309 | 310 | static void yyensure_buffer_stack ( void ); 311 | static void yy_load_buffer_state ( void ); 312 | static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); 313 | #define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) 314 | 315 | YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); 316 | YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); 317 | YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); 318 | 319 | void *yyalloc ( yy_size_t ); 320 | void *yyrealloc ( void *, yy_size_t ); 321 | void yyfree ( void * ); 322 | 323 | #define yy_new_buffer yy_create_buffer 324 | #define yy_set_interactive(is_interactive) \ 325 | { \ 326 | if ( ! YY_CURRENT_BUFFER ){ \ 327 | yyensure_buffer_stack (); \ 328 | YY_CURRENT_BUFFER_LVALUE = \ 329 | yy_create_buffer( yyin, YY_BUF_SIZE ); \ 330 | } \ 331 | YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ 332 | } 333 | #define yy_set_bol(at_bol) \ 334 | { \ 335 | if ( ! YY_CURRENT_BUFFER ){\ 336 | yyensure_buffer_stack (); \ 337 | YY_CURRENT_BUFFER_LVALUE = \ 338 | yy_create_buffer( yyin, YY_BUF_SIZE ); \ 339 | } \ 340 | YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ 341 | } 342 | #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) 343 | 344 | #define yywrap() (/*CONSTCOND*/1) 345 | #define YY_SKIP_YYWRAP 346 | typedef flex_uint8_t YY_CHAR; 347 | 348 | FILE *yyin = NULL, *yyout = NULL; 349 | 350 | typedef int yy_state_type; 351 | 352 | extern int yylineno; 353 | int yylineno = 1; 354 | 355 | extern char *yytext; 356 | #ifdef yytext_ptr 357 | #undef yytext_ptr 358 | #endif 359 | #define yytext_ptr yytext 360 | 361 | static yy_state_type yy_get_previous_state ( void ); 362 | static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); 363 | static int yy_get_next_buffer ( void ); 364 | static void yynoreturn yy_fatal_error ( const char* msg ); 365 | 366 | /* Done after the current pattern has been matched and before the 367 | * corresponding action - sets up yytext. 368 | */ 369 | #define YY_DO_BEFORE_ACTION \ 370 | (yytext_ptr) = yy_bp; \ 371 | yyleng = (int) (yy_cp - yy_bp); \ 372 | (yy_hold_char) = *yy_cp; \ 373 | *yy_cp = '\0'; \ 374 | (yy_c_buf_p) = yy_cp; 375 | #define YY_NUM_RULES 9 376 | #define YY_END_OF_BUFFER 10 377 | /* This struct is not used in this scanner, 378 | but its presence is necessary. */ 379 | struct yy_trans_info 380 | { 381 | flex_int32_t yy_verify; 382 | flex_int32_t yy_nxt; 383 | }; 384 | static const flex_int16_t yy_accept[17] = 385 | { 0, 386 | 0, 0, 10, 9, 8, 5, 3, 4, 6, 1, 387 | 7, 0, 1, 2, 1, 0 388 | } ; 389 | 390 | static const YY_CHAR yy_ec[256] = 391 | { 0, 392 | 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 393 | 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 394 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 395 | 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 396 | 1, 4, 5, 1, 6, 1, 7, 8, 8, 8, 397 | 8, 8, 8, 8, 8, 8, 8, 1, 9, 1, 398 | 1, 1, 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 | 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 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 1, 1, 1, 1, 1, 413 | 414 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 415 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 416 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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 420 | } ; 421 | 422 | static const YY_CHAR yy_meta[10] = 423 | { 0, 424 | 1, 1, 2, 1, 1, 1, 1, 1, 1 425 | } ; 426 | 427 | static const flex_int16_t yy_base[18] = 428 | { 0, 429 | 0, 0, 16, 17, 17, 17, 17, 17, 17, 7, 430 | 17, 6, 5, 4, 3, 17, 9 431 | } ; 432 | 433 | static const flex_int16_t yy_def[18] = 434 | { 0, 435 | 16, 1, 16, 16, 16, 16, 16, 16, 16, 17, 436 | 16, 16, 17, 16, 17, 0, 16 437 | } ; 438 | 439 | static const flex_int16_t yy_nxt[27] = 440 | { 0, 441 | 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 442 | 15, 14, 15, 14, 13, 16, 3, 16, 16, 16, 443 | 16, 16, 16, 16, 16, 16 444 | } ; 445 | 446 | static const flex_int16_t yy_chk[27] = 447 | { 0, 448 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 17, 449 | 15, 14, 13, 12, 10, 3, 16, 16, 16, 16, 450 | 16, 16, 16, 16, 16, 16 451 | } ; 452 | 453 | /* Table of booleans, true if rule could match eol. */ 454 | static const flex_int32_t yy_rule_can_match_eol[10] = 455 | { 0, 456 | 0, 0, 0, 0, 0, 0, 0, 1, 0, }; 457 | 458 | static yy_state_type yy_last_accepting_state; 459 | static char *yy_last_accepting_cpos; 460 | 461 | extern int yy_flex_debug; 462 | int yy_flex_debug = 0; 463 | 464 | /* The intent behind this definition is that it'll catch 465 | * any uses of REJECT which flex missed. 466 | */ 467 | #define REJECT reject_used_but_not_detected 468 | #define yymore() yymore_used_but_not_detected 469 | #define YY_MORE_ADJ 0 470 | #define YY_RESTORE_YY_MORE_OFFSET 471 | char *yytext; 472 | #line 1 "scanner.lex" 473 | #line 2 "scanner.lex" 474 | #include "parser.tab.hpp" 475 | extern "C" int yylex(); 476 | #line 477 "scanner.c" 477 | #line 478 "scanner.c" 478 | 479 | #define INITIAL 0 480 | 481 | #ifndef YY_NO_UNISTD_H 482 | /* Special case for "unistd.h", since it is non-ANSI. We include it way 483 | * down here because we want the user's section 1 to have been scanned first. 484 | * The user has a chance to override it with an option. 485 | */ 486 | #include 487 | #endif 488 | 489 | #ifndef YY_EXTRA_TYPE 490 | #define YY_EXTRA_TYPE void * 491 | #endif 492 | 493 | static int yy_init_globals ( void ); 494 | 495 | /* Accessor methods to globals. 496 | These are made visible to non-reentrant scanners for convenience. */ 497 | 498 | int yylex_destroy ( void ); 499 | 500 | int yyget_debug ( void ); 501 | 502 | void yyset_debug ( int debug_flag ); 503 | 504 | YY_EXTRA_TYPE yyget_extra ( void ); 505 | 506 | void yyset_extra ( YY_EXTRA_TYPE user_defined ); 507 | 508 | FILE *yyget_in ( void ); 509 | 510 | void yyset_in ( FILE * _in_str ); 511 | 512 | FILE *yyget_out ( void ); 513 | 514 | void yyset_out ( FILE * _out_str ); 515 | 516 | int yyget_leng ( void ); 517 | 518 | char *yyget_text ( void ); 519 | 520 | int yyget_lineno ( void ); 521 | 522 | void yyset_lineno ( int _line_number ); 523 | 524 | /* Macros after this point can all be overridden by user definitions in 525 | * section 1. 526 | */ 527 | 528 | #ifndef YY_SKIP_YYWRAP 529 | #ifdef __cplusplus 530 | extern "C" int yywrap ( void ); 531 | #else 532 | extern int yywrap ( void ); 533 | #endif 534 | #endif 535 | 536 | #ifndef YY_NO_UNPUT 537 | 538 | static void yyunput ( int c, char *buf_ptr ); 539 | 540 | #endif 541 | 542 | #ifndef yytext_ptr 543 | static void yy_flex_strncpy ( char *, const char *, int ); 544 | #endif 545 | 546 | #ifdef YY_NEED_STRLEN 547 | static int yy_flex_strlen ( const char * ); 548 | #endif 549 | 550 | #ifndef YY_NO_INPUT 551 | #ifdef __cplusplus 552 | static int yyinput ( void ); 553 | #else 554 | static int input ( void ); 555 | #endif 556 | 557 | #endif 558 | 559 | /* Amount of stuff to slurp up with each read. */ 560 | #ifndef YY_READ_BUF_SIZE 561 | #ifdef __ia64__ 562 | /* On IA-64, the buffer size is 16k, not 8k */ 563 | #define YY_READ_BUF_SIZE 16384 564 | #else 565 | #define YY_READ_BUF_SIZE 8192 566 | #endif /* __ia64__ */ 567 | #endif 568 | 569 | /* Copy whatever the last rule matched to the standard output. */ 570 | #ifndef ECHO 571 | /* This used to be an fputs(), but since the string might contain NUL's, 572 | * we now use fwrite(). 573 | */ 574 | #define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) 575 | #endif 576 | 577 | /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, 578 | * is returned in "result". 579 | */ 580 | #ifndef YY_INPUT 581 | #define YY_INPUT(buf,result,max_size) \ 582 | if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ 583 | { \ 584 | int c = '*'; \ 585 | int n; \ 586 | for ( n = 0; n < max_size && \ 587 | (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ 588 | buf[n] = (char) c; \ 589 | if ( c == '\n' ) \ 590 | buf[n++] = (char) c; \ 591 | if ( c == EOF && ferror( yyin ) ) \ 592 | YY_FATAL_ERROR( "input in flex scanner failed" ); \ 593 | result = n; \ 594 | } \ 595 | else \ 596 | { \ 597 | errno=0; \ 598 | while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ 599 | { \ 600 | if( errno != EINTR) \ 601 | { \ 602 | YY_FATAL_ERROR( "input in flex scanner failed" ); \ 603 | break; \ 604 | } \ 605 | errno=0; \ 606 | clearerr(yyin); \ 607 | } \ 608 | }\ 609 | \ 610 | 611 | #endif 612 | 613 | /* No semi-colon after return; correct usage is to write "yyterminate();" - 614 | * we don't want an extra ';' after the "return" because that will cause 615 | * some compilers to complain about unreachable statements. 616 | */ 617 | #ifndef yyterminate 618 | #define yyterminate() return YY_NULL 619 | #endif 620 | 621 | /* Number of entries by which start-condition stack grows. */ 622 | #ifndef YY_START_STACK_INCR 623 | #define YY_START_STACK_INCR 25 624 | #endif 625 | 626 | /* Report a fatal error. */ 627 | #ifndef YY_FATAL_ERROR 628 | #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) 629 | #endif 630 | 631 | /* end tables serialization structures and prototypes */ 632 | 633 | /* Default declaration of generated scanner - a define so the user can 634 | * easily add parameters. 635 | */ 636 | #ifndef YY_DECL 637 | #define YY_DECL_IS_OURS 1 638 | 639 | extern int yylex (void); 640 | 641 | #define YY_DECL int yylex (void) 642 | #endif /* !YY_DECL */ 643 | 644 | /* Code executed at the beginning of each rule, after yytext and yyleng 645 | * have been set up. 646 | */ 647 | #ifndef YY_USER_ACTION 648 | #define YY_USER_ACTION 649 | #endif 650 | 651 | /* Code executed at the end of each rule. */ 652 | #ifndef YY_BREAK 653 | #define YY_BREAK /*LINTED*/break; 654 | #endif 655 | 656 | #define YY_RULE_SETUP \ 657 | YY_USER_ACTION 658 | 659 | /** The main scanner function which does all the work. 660 | */ 661 | YY_DECL 662 | { 663 | yy_state_type yy_current_state; 664 | char *yy_cp, *yy_bp; 665 | int yy_act; 666 | 667 | if ( !(yy_init) ) 668 | { 669 | (yy_init) = 1; 670 | 671 | #ifdef YY_USER_INIT 672 | YY_USER_INIT; 673 | #endif 674 | 675 | if ( ! (yy_start) ) 676 | (yy_start) = 1; /* first start state */ 677 | 678 | if ( ! yyin ) 679 | yyin = stdin; 680 | 681 | if ( ! yyout ) 682 | yyout = stdout; 683 | 684 | if ( ! YY_CURRENT_BUFFER ) { 685 | yyensure_buffer_stack (); 686 | YY_CURRENT_BUFFER_LVALUE = 687 | yy_create_buffer( yyin, YY_BUF_SIZE ); 688 | } 689 | 690 | yy_load_buffer_state( ); 691 | } 692 | 693 | { 694 | #line 8 "scanner.lex" 695 | 696 | #line 697 "scanner.c" 697 | 698 | while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ 699 | { 700 | yy_cp = (yy_c_buf_p); 701 | 702 | /* Support of yytext. */ 703 | *yy_cp = (yy_hold_char); 704 | 705 | /* yy_bp points to the position in yy_ch_buf of the start of 706 | * the current run. 707 | */ 708 | yy_bp = yy_cp; 709 | 710 | yy_current_state = (yy_start); 711 | yy_match: 712 | do 713 | { 714 | YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; 715 | if ( yy_accept[yy_current_state] ) 716 | { 717 | (yy_last_accepting_state) = yy_current_state; 718 | (yy_last_accepting_cpos) = yy_cp; 719 | } 720 | while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 721 | { 722 | yy_current_state = (int) yy_def[yy_current_state]; 723 | if ( yy_current_state >= 17 ) 724 | yy_c = yy_meta[yy_c]; 725 | } 726 | yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; 727 | ++yy_cp; 728 | } 729 | while ( yy_base[yy_current_state] != 17 ); 730 | 731 | yy_find_action: 732 | yy_act = yy_accept[yy_current_state]; 733 | if ( yy_act == 0 ) 734 | { /* have to back up */ 735 | yy_cp = (yy_last_accepting_cpos); 736 | yy_current_state = (yy_last_accepting_state); 737 | yy_act = yy_accept[yy_current_state]; 738 | } 739 | 740 | YY_DO_BEFORE_ACTION; 741 | 742 | if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) 743 | { 744 | int yyl; 745 | for ( yyl = 0; yyl < yyleng; ++yyl ) 746 | if ( yytext[yyl] == '\n' ) 747 | 748 | yylineno++; 749 | ; 750 | } 751 | 752 | do_action: /* This label is used only to access EOF actions. */ 753 | 754 | switch ( yy_act ) 755 | { /* beginning of action switch */ 756 | case 0: /* must back up */ 757 | /* undo the effects of YY_DO_BEFORE_ACTION */ 758 | *yy_cp = (yy_hold_char); 759 | yy_cp = (yy_last_accepting_cpos); 760 | yy_current_state = (yy_last_accepting_state); 761 | goto yy_find_action; 762 | 763 | case 1: 764 | YY_RULE_SETUP 765 | #line 9 "scanner.lex" 766 | { yylval.intVal = atoi(yytext); return INTEGER_LITERAL; } 767 | YY_BREAK 768 | case 2: 769 | YY_RULE_SETUP 770 | #line 10 "scanner.lex" 771 | { yylval.floatVal = atof(yytext); return FLOAT_LITERAL; } 772 | YY_BREAK 773 | case 3: 774 | YY_RULE_SETUP 775 | #line 11 "scanner.lex" 776 | { return PLUS; } 777 | YY_BREAK 778 | case 4: 779 | YY_RULE_SETUP 780 | #line 12 "scanner.lex" 781 | { return MINUS; } 782 | YY_BREAK 783 | case 5: 784 | YY_RULE_SETUP 785 | #line 13 "scanner.lex" 786 | { return MULT; } 787 | YY_BREAK 788 | case 6: 789 | YY_RULE_SETUP 790 | #line 14 "scanner.lex" 791 | { return DIV; } 792 | YY_BREAK 793 | case 7: 794 | YY_RULE_SETUP 795 | #line 15 "scanner.lex" 796 | { return SEMI; } 797 | YY_BREAK 798 | case 8: 799 | /* rule 8 can match eol */ 800 | YY_RULE_SETUP 801 | #line 16 "scanner.lex" 802 | ; /* ignore whitespace */ 803 | YY_BREAK 804 | case 9: 805 | YY_RULE_SETUP 806 | #line 18 "scanner.lex" 807 | ECHO; 808 | YY_BREAK 809 | #line 810 "scanner.c" 810 | case YY_STATE_EOF(INITIAL): 811 | yyterminate(); 812 | 813 | case YY_END_OF_BUFFER: 814 | { 815 | /* Amount of text matched not including the EOB char. */ 816 | int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; 817 | 818 | /* Undo the effects of YY_DO_BEFORE_ACTION. */ 819 | *yy_cp = (yy_hold_char); 820 | YY_RESTORE_YY_MORE_OFFSET 821 | 822 | if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) 823 | { 824 | /* We're scanning a new file or input source. It's 825 | * possible that this happened because the user 826 | * just pointed yyin at a new source and called 827 | * yylex(). If so, then we have to assure 828 | * consistency between YY_CURRENT_BUFFER and our 829 | * globals. Here is the right place to do so, because 830 | * this is the first action (other than possibly a 831 | * back-up) that will match for the new input source. 832 | */ 833 | (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; 834 | YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; 835 | YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; 836 | } 837 | 838 | /* Note that here we test for yy_c_buf_p "<=" to the position 839 | * of the first EOB in the buffer, since yy_c_buf_p will 840 | * already have been incremented past the NUL character 841 | * (since all states make transitions on EOB to the 842 | * end-of-buffer state). Contrast this with the test 843 | * in input(). 844 | */ 845 | if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) 846 | { /* This was really a NUL. */ 847 | yy_state_type yy_next_state; 848 | 849 | (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; 850 | 851 | yy_current_state = yy_get_previous_state( ); 852 | 853 | /* Okay, we're now positioned to make the NUL 854 | * transition. We couldn't have 855 | * yy_get_previous_state() go ahead and do it 856 | * for us because it doesn't know how to deal 857 | * with the possibility of jamming (and we don't 858 | * want to build jamming into it because then it 859 | * will run more slowly). 860 | */ 861 | 862 | yy_next_state = yy_try_NUL_trans( yy_current_state ); 863 | 864 | yy_bp = (yytext_ptr) + YY_MORE_ADJ; 865 | 866 | if ( yy_next_state ) 867 | { 868 | /* Consume the NUL. */ 869 | yy_cp = ++(yy_c_buf_p); 870 | yy_current_state = yy_next_state; 871 | goto yy_match; 872 | } 873 | 874 | else 875 | { 876 | yy_cp = (yy_c_buf_p); 877 | goto yy_find_action; 878 | } 879 | } 880 | 881 | else switch ( yy_get_next_buffer( ) ) 882 | { 883 | case EOB_ACT_END_OF_FILE: 884 | { 885 | (yy_did_buffer_switch_on_eof) = 0; 886 | 887 | if ( yywrap( ) ) 888 | { 889 | /* Note: because we've taken care in 890 | * yy_get_next_buffer() to have set up 891 | * yytext, we can now set up 892 | * yy_c_buf_p so that if some total 893 | * hoser (like flex itself) wants to 894 | * call the scanner after we return the 895 | * YY_NULL, it'll still work - another 896 | * YY_NULL will get returned. 897 | */ 898 | (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; 899 | 900 | yy_act = YY_STATE_EOF(YY_START); 901 | goto do_action; 902 | } 903 | 904 | else 905 | { 906 | if ( ! (yy_did_buffer_switch_on_eof) ) 907 | YY_NEW_FILE; 908 | } 909 | break; 910 | } 911 | 912 | case EOB_ACT_CONTINUE_SCAN: 913 | (yy_c_buf_p) = 914 | (yytext_ptr) + yy_amount_of_matched_text; 915 | 916 | yy_current_state = yy_get_previous_state( ); 917 | 918 | yy_cp = (yy_c_buf_p); 919 | yy_bp = (yytext_ptr) + YY_MORE_ADJ; 920 | goto yy_match; 921 | 922 | case EOB_ACT_LAST_MATCH: 923 | (yy_c_buf_p) = 924 | &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; 925 | 926 | yy_current_state = yy_get_previous_state( ); 927 | 928 | yy_cp = (yy_c_buf_p); 929 | yy_bp = (yytext_ptr) + YY_MORE_ADJ; 930 | goto yy_find_action; 931 | } 932 | break; 933 | } 934 | 935 | default: 936 | YY_FATAL_ERROR( 937 | "fatal flex scanner internal error--no action found" ); 938 | } /* end of action switch */ 939 | } /* end of scanning one token */ 940 | } /* end of user's declarations */ 941 | } /* end of yylex */ 942 | 943 | /* yy_get_next_buffer - try to read in a new buffer 944 | * 945 | * Returns a code representing an action: 946 | * EOB_ACT_LAST_MATCH - 947 | * EOB_ACT_CONTINUE_SCAN - continue scanning from current position 948 | * EOB_ACT_END_OF_FILE - end of file 949 | */ 950 | static int yy_get_next_buffer (void) 951 | { 952 | char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; 953 | char *source = (yytext_ptr); 954 | int number_to_move, i; 955 | int ret_val; 956 | 957 | if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) 958 | YY_FATAL_ERROR( 959 | "fatal flex scanner internal error--end of buffer missed" ); 960 | 961 | if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) 962 | { /* Don't try to fill the buffer, so this is an EOF. */ 963 | if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) 964 | { 965 | /* We matched a single character, the EOB, so 966 | * treat this as a final EOF. 967 | */ 968 | return EOB_ACT_END_OF_FILE; 969 | } 970 | 971 | else 972 | { 973 | /* We matched some text prior to the EOB, first 974 | * process it. 975 | */ 976 | return EOB_ACT_LAST_MATCH; 977 | } 978 | } 979 | 980 | /* Try to read more data. */ 981 | 982 | /* First move last chars to start of buffer. */ 983 | number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); 984 | 985 | for ( i = 0; i < number_to_move; ++i ) 986 | *(dest++) = *(source++); 987 | 988 | if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) 989 | /* don't do the read, it's not guaranteed to return an EOF, 990 | * just force an EOF 991 | */ 992 | YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; 993 | 994 | else 995 | { 996 | int num_to_read = 997 | YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; 998 | 999 | while ( num_to_read <= 0 ) 1000 | { /* Not enough room in the buffer - grow it. */ 1001 | 1002 | /* just a shorter name for the current buffer */ 1003 | YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; 1004 | 1005 | int yy_c_buf_p_offset = 1006 | (int) ((yy_c_buf_p) - b->yy_ch_buf); 1007 | 1008 | if ( b->yy_is_our_buffer ) 1009 | { 1010 | int new_size = b->yy_buf_size * 2; 1011 | 1012 | if ( new_size <= 0 ) 1013 | b->yy_buf_size += b->yy_buf_size / 8; 1014 | else 1015 | b->yy_buf_size *= 2; 1016 | 1017 | b->yy_ch_buf = (char *) 1018 | /* Include room in for 2 EOB chars. */ 1019 | yyrealloc( (void *) b->yy_ch_buf, 1020 | (yy_size_t) (b->yy_buf_size + 2) ); 1021 | } 1022 | else 1023 | /* Can't grow it, we don't own it. */ 1024 | b->yy_ch_buf = NULL; 1025 | 1026 | if ( ! b->yy_ch_buf ) 1027 | YY_FATAL_ERROR( 1028 | "fatal error - scanner input buffer overflow" ); 1029 | 1030 | (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; 1031 | 1032 | num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - 1033 | number_to_move - 1; 1034 | 1035 | } 1036 | 1037 | if ( num_to_read > YY_READ_BUF_SIZE ) 1038 | num_to_read = YY_READ_BUF_SIZE; 1039 | 1040 | /* Read in more data. */ 1041 | YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), 1042 | (yy_n_chars), num_to_read ); 1043 | 1044 | YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); 1045 | } 1046 | 1047 | if ( (yy_n_chars) == 0 ) 1048 | { 1049 | if ( number_to_move == YY_MORE_ADJ ) 1050 | { 1051 | ret_val = EOB_ACT_END_OF_FILE; 1052 | yyrestart( yyin ); 1053 | } 1054 | 1055 | else 1056 | { 1057 | ret_val = EOB_ACT_LAST_MATCH; 1058 | YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = 1059 | YY_BUFFER_EOF_PENDING; 1060 | } 1061 | } 1062 | 1063 | else 1064 | ret_val = EOB_ACT_CONTINUE_SCAN; 1065 | 1066 | if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { 1067 | /* Extend the array by 50%, plus the number we really need. */ 1068 | int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); 1069 | YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( 1070 | (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); 1071 | if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) 1072 | YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); 1073 | /* "- 2" to take care of EOB's */ 1074 | YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); 1075 | } 1076 | 1077 | (yy_n_chars) += number_to_move; 1078 | YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; 1079 | YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; 1080 | 1081 | (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; 1082 | 1083 | return ret_val; 1084 | } 1085 | 1086 | /* yy_get_previous_state - get the state just before the EOB char was reached */ 1087 | 1088 | static yy_state_type yy_get_previous_state (void) 1089 | { 1090 | yy_state_type yy_current_state; 1091 | char *yy_cp; 1092 | 1093 | yy_current_state = (yy_start); 1094 | 1095 | for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) 1096 | { 1097 | YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); 1098 | if ( yy_accept[yy_current_state] ) 1099 | { 1100 | (yy_last_accepting_state) = yy_current_state; 1101 | (yy_last_accepting_cpos) = yy_cp; 1102 | } 1103 | while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 1104 | { 1105 | yy_current_state = (int) yy_def[yy_current_state]; 1106 | if ( yy_current_state >= 17 ) 1107 | yy_c = yy_meta[yy_c]; 1108 | } 1109 | yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; 1110 | } 1111 | 1112 | return yy_current_state; 1113 | } 1114 | 1115 | /* yy_try_NUL_trans - try to make a transition on the NUL character 1116 | * 1117 | * synopsis 1118 | * next_state = yy_try_NUL_trans( current_state ); 1119 | */ 1120 | static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) 1121 | { 1122 | int yy_is_jam; 1123 | char *yy_cp = (yy_c_buf_p); 1124 | 1125 | YY_CHAR yy_c = 1; 1126 | if ( yy_accept[yy_current_state] ) 1127 | { 1128 | (yy_last_accepting_state) = yy_current_state; 1129 | (yy_last_accepting_cpos) = yy_cp; 1130 | } 1131 | while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 1132 | { 1133 | yy_current_state = (int) yy_def[yy_current_state]; 1134 | if ( yy_current_state >= 17 ) 1135 | yy_c = yy_meta[yy_c]; 1136 | } 1137 | yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; 1138 | yy_is_jam = (yy_current_state == 16); 1139 | 1140 | return yy_is_jam ? 0 : yy_current_state; 1141 | } 1142 | 1143 | #ifndef YY_NO_UNPUT 1144 | 1145 | static void yyunput (int c, char * yy_bp ) 1146 | { 1147 | char *yy_cp; 1148 | 1149 | yy_cp = (yy_c_buf_p); 1150 | 1151 | /* undo effects of setting up yytext */ 1152 | *yy_cp = (yy_hold_char); 1153 | 1154 | if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) 1155 | { /* need to shift things up to make room */ 1156 | /* +2 for EOB chars. */ 1157 | int number_to_move = (yy_n_chars) + 2; 1158 | char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ 1159 | YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; 1160 | char *source = 1161 | &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; 1162 | 1163 | while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) 1164 | *--dest = *--source; 1165 | 1166 | yy_cp += (int) (dest - source); 1167 | yy_bp += (int) (dest - source); 1168 | YY_CURRENT_BUFFER_LVALUE->yy_n_chars = 1169 | (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; 1170 | 1171 | if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) 1172 | YY_FATAL_ERROR( "flex scanner push-back overflow" ); 1173 | } 1174 | 1175 | *--yy_cp = (char) c; 1176 | 1177 | if ( c == '\n' ){ 1178 | --yylineno; 1179 | } 1180 | 1181 | (yytext_ptr) = yy_bp; 1182 | (yy_hold_char) = *yy_cp; 1183 | (yy_c_buf_p) = yy_cp; 1184 | } 1185 | 1186 | #endif 1187 | 1188 | #ifndef YY_NO_INPUT 1189 | #ifdef __cplusplus 1190 | static int yyinput (void) 1191 | #else 1192 | static int input (void) 1193 | #endif 1194 | 1195 | { 1196 | int c; 1197 | 1198 | *(yy_c_buf_p) = (yy_hold_char); 1199 | 1200 | if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) 1201 | { 1202 | /* yy_c_buf_p now points to the character we want to return. 1203 | * If this occurs *before* the EOB characters, then it's a 1204 | * valid NUL; if not, then we've hit the end of the buffer. 1205 | */ 1206 | if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) 1207 | /* This was really a NUL. */ 1208 | *(yy_c_buf_p) = '\0'; 1209 | 1210 | else 1211 | { /* need more input */ 1212 | int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); 1213 | ++(yy_c_buf_p); 1214 | 1215 | switch ( yy_get_next_buffer( ) ) 1216 | { 1217 | case EOB_ACT_LAST_MATCH: 1218 | /* This happens because yy_g_n_b() 1219 | * sees that we've accumulated a 1220 | * token and flags that we need to 1221 | * try matching the token before 1222 | * proceeding. But for input(), 1223 | * there's no matching to consider. 1224 | * So convert the EOB_ACT_LAST_MATCH 1225 | * to EOB_ACT_END_OF_FILE. 1226 | */ 1227 | 1228 | /* Reset buffer status. */ 1229 | yyrestart( yyin ); 1230 | 1231 | /*FALLTHROUGH*/ 1232 | 1233 | case EOB_ACT_END_OF_FILE: 1234 | { 1235 | if ( yywrap( ) ) 1236 | return 0; 1237 | 1238 | if ( ! (yy_did_buffer_switch_on_eof) ) 1239 | YY_NEW_FILE; 1240 | #ifdef __cplusplus 1241 | return yyinput(); 1242 | #else 1243 | return input(); 1244 | #endif 1245 | } 1246 | 1247 | case EOB_ACT_CONTINUE_SCAN: 1248 | (yy_c_buf_p) = (yytext_ptr) + offset; 1249 | break; 1250 | } 1251 | } 1252 | } 1253 | 1254 | c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ 1255 | *(yy_c_buf_p) = '\0'; /* preserve yytext */ 1256 | (yy_hold_char) = *++(yy_c_buf_p); 1257 | 1258 | if ( c == '\n' ) 1259 | 1260 | yylineno++; 1261 | ; 1262 | 1263 | return c; 1264 | } 1265 | #endif /* ifndef YY_NO_INPUT */ 1266 | 1267 | /** Immediately switch to a different input stream. 1268 | * @param input_file A readable stream. 1269 | * 1270 | * @note This function does not reset the start condition to @c INITIAL . 1271 | */ 1272 | void yyrestart (FILE * input_file ) 1273 | { 1274 | 1275 | if ( ! YY_CURRENT_BUFFER ){ 1276 | yyensure_buffer_stack (); 1277 | YY_CURRENT_BUFFER_LVALUE = 1278 | yy_create_buffer( yyin, YY_BUF_SIZE ); 1279 | } 1280 | 1281 | yy_init_buffer( YY_CURRENT_BUFFER, input_file ); 1282 | yy_load_buffer_state( ); 1283 | } 1284 | 1285 | /** Switch to a different input buffer. 1286 | * @param new_buffer The new input buffer. 1287 | * 1288 | */ 1289 | void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) 1290 | { 1291 | 1292 | /* TODO. We should be able to replace this entire function body 1293 | * with 1294 | * yypop_buffer_state(); 1295 | * yypush_buffer_state(new_buffer); 1296 | */ 1297 | yyensure_buffer_stack (); 1298 | if ( YY_CURRENT_BUFFER == new_buffer ) 1299 | return; 1300 | 1301 | if ( YY_CURRENT_BUFFER ) 1302 | { 1303 | /* Flush out information for old buffer. */ 1304 | *(yy_c_buf_p) = (yy_hold_char); 1305 | YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); 1306 | YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); 1307 | } 1308 | 1309 | YY_CURRENT_BUFFER_LVALUE = new_buffer; 1310 | yy_load_buffer_state( ); 1311 | 1312 | /* We don't actually know whether we did this switch during 1313 | * EOF (yywrap()) processing, but the only time this flag 1314 | * is looked at is after yywrap() is called, so it's safe 1315 | * to go ahead and always set it. 1316 | */ 1317 | (yy_did_buffer_switch_on_eof) = 1; 1318 | } 1319 | 1320 | static void yy_load_buffer_state (void) 1321 | { 1322 | (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; 1323 | (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; 1324 | yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; 1325 | (yy_hold_char) = *(yy_c_buf_p); 1326 | } 1327 | 1328 | /** Allocate and initialize an input buffer state. 1329 | * @param file A readable stream. 1330 | * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. 1331 | * 1332 | * @return the allocated buffer state. 1333 | */ 1334 | YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) 1335 | { 1336 | YY_BUFFER_STATE b; 1337 | 1338 | b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); 1339 | if ( ! b ) 1340 | YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); 1341 | 1342 | b->yy_buf_size = size; 1343 | 1344 | /* yy_ch_buf has to be 2 characters longer than the size given because 1345 | * we need to put in 2 end-of-buffer characters. 1346 | */ 1347 | b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); 1348 | if ( ! b->yy_ch_buf ) 1349 | YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); 1350 | 1351 | b->yy_is_our_buffer = 1; 1352 | 1353 | yy_init_buffer( b, file ); 1354 | 1355 | return b; 1356 | } 1357 | 1358 | /** Destroy the buffer. 1359 | * @param b a buffer created with yy_create_buffer() 1360 | * 1361 | */ 1362 | void yy_delete_buffer (YY_BUFFER_STATE b ) 1363 | { 1364 | 1365 | if ( ! b ) 1366 | return; 1367 | 1368 | if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ 1369 | YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; 1370 | 1371 | if ( b->yy_is_our_buffer ) 1372 | yyfree( (void *) b->yy_ch_buf ); 1373 | 1374 | yyfree( (void *) b ); 1375 | } 1376 | 1377 | /* Initializes or reinitializes a buffer. 1378 | * This function is sometimes called more than once on the same buffer, 1379 | * such as during a yyrestart() or at EOF. 1380 | */ 1381 | static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) 1382 | 1383 | { 1384 | int oerrno = errno; 1385 | 1386 | yy_flush_buffer( b ); 1387 | 1388 | b->yy_input_file = file; 1389 | b->yy_fill_buffer = 1; 1390 | 1391 | /* If b is the current buffer, then yy_init_buffer was _probably_ 1392 | * called from yyrestart() or through yy_get_next_buffer. 1393 | * In that case, we don't want to reset the lineno or column. 1394 | */ 1395 | if (b != YY_CURRENT_BUFFER){ 1396 | b->yy_bs_lineno = 1; 1397 | b->yy_bs_column = 0; 1398 | } 1399 | 1400 | b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; 1401 | 1402 | errno = oerrno; 1403 | } 1404 | 1405 | /** Discard all buffered characters. On the next scan, YY_INPUT will be called. 1406 | * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. 1407 | * 1408 | */ 1409 | void yy_flush_buffer (YY_BUFFER_STATE b ) 1410 | { 1411 | if ( ! b ) 1412 | return; 1413 | 1414 | b->yy_n_chars = 0; 1415 | 1416 | /* We always need two end-of-buffer characters. The first causes 1417 | * a transition to the end-of-buffer state. The second causes 1418 | * a jam in that state. 1419 | */ 1420 | b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; 1421 | b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; 1422 | 1423 | b->yy_buf_pos = &b->yy_ch_buf[0]; 1424 | 1425 | b->yy_at_bol = 1; 1426 | b->yy_buffer_status = YY_BUFFER_NEW; 1427 | 1428 | if ( b == YY_CURRENT_BUFFER ) 1429 | yy_load_buffer_state( ); 1430 | } 1431 | 1432 | /** Pushes the new state onto the stack. The new state becomes 1433 | * the current state. This function will allocate the stack 1434 | * if necessary. 1435 | * @param new_buffer The new state. 1436 | * 1437 | */ 1438 | void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) 1439 | { 1440 | if (new_buffer == NULL) 1441 | return; 1442 | 1443 | yyensure_buffer_stack(); 1444 | 1445 | /* This block is copied from yy_switch_to_buffer. */ 1446 | if ( YY_CURRENT_BUFFER ) 1447 | { 1448 | /* Flush out information for old buffer. */ 1449 | *(yy_c_buf_p) = (yy_hold_char); 1450 | YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); 1451 | YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); 1452 | } 1453 | 1454 | /* Only push if top exists. Otherwise, replace top. */ 1455 | if (YY_CURRENT_BUFFER) 1456 | (yy_buffer_stack_top)++; 1457 | YY_CURRENT_BUFFER_LVALUE = new_buffer; 1458 | 1459 | /* copied from yy_switch_to_buffer. */ 1460 | yy_load_buffer_state( ); 1461 | (yy_did_buffer_switch_on_eof) = 1; 1462 | } 1463 | 1464 | /** Removes and deletes the top of the stack, if present. 1465 | * The next element becomes the new top. 1466 | * 1467 | */ 1468 | void yypop_buffer_state (void) 1469 | { 1470 | if (!YY_CURRENT_BUFFER) 1471 | return; 1472 | 1473 | yy_delete_buffer(YY_CURRENT_BUFFER ); 1474 | YY_CURRENT_BUFFER_LVALUE = NULL; 1475 | if ((yy_buffer_stack_top) > 0) 1476 | --(yy_buffer_stack_top); 1477 | 1478 | if (YY_CURRENT_BUFFER) { 1479 | yy_load_buffer_state( ); 1480 | (yy_did_buffer_switch_on_eof) = 1; 1481 | } 1482 | } 1483 | 1484 | /* Allocates the stack if it does not exist. 1485 | * Guarantees space for at least one push. 1486 | */ 1487 | static void yyensure_buffer_stack (void) 1488 | { 1489 | yy_size_t num_to_alloc; 1490 | 1491 | if (!(yy_buffer_stack)) { 1492 | 1493 | /* First allocation is just for 2 elements, since we don't know if this 1494 | * scanner will even need a stack. We use 2 instead of 1 to avoid an 1495 | * immediate realloc on the next call. 1496 | */ 1497 | num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ 1498 | (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc 1499 | (num_to_alloc * sizeof(struct yy_buffer_state*) 1500 | ); 1501 | if ( ! (yy_buffer_stack) ) 1502 | YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); 1503 | 1504 | memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); 1505 | 1506 | (yy_buffer_stack_max) = num_to_alloc; 1507 | (yy_buffer_stack_top) = 0; 1508 | return; 1509 | } 1510 | 1511 | if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ 1512 | 1513 | /* Increase the buffer to prepare for a possible push. */ 1514 | yy_size_t grow_size = 8 /* arbitrary grow size */; 1515 | 1516 | num_to_alloc = (yy_buffer_stack_max) + grow_size; 1517 | (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc 1518 | ((yy_buffer_stack), 1519 | num_to_alloc * sizeof(struct yy_buffer_state*) 1520 | ); 1521 | if ( ! (yy_buffer_stack) ) 1522 | YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); 1523 | 1524 | /* zero only the new slots.*/ 1525 | memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); 1526 | (yy_buffer_stack_max) = num_to_alloc; 1527 | } 1528 | } 1529 | 1530 | /** Setup the input buffer state to scan directly from a user-specified character buffer. 1531 | * @param base the character buffer 1532 | * @param size the size in bytes of the character buffer 1533 | * 1534 | * @return the newly allocated buffer state object. 1535 | */ 1536 | YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) 1537 | { 1538 | YY_BUFFER_STATE b; 1539 | 1540 | if ( size < 2 || 1541 | base[size-2] != YY_END_OF_BUFFER_CHAR || 1542 | base[size-1] != YY_END_OF_BUFFER_CHAR ) 1543 | /* They forgot to leave room for the EOB's. */ 1544 | return NULL; 1545 | 1546 | b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); 1547 | if ( ! b ) 1548 | YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); 1549 | 1550 | b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ 1551 | b->yy_buf_pos = b->yy_ch_buf = base; 1552 | b->yy_is_our_buffer = 0; 1553 | b->yy_input_file = NULL; 1554 | b->yy_n_chars = b->yy_buf_size; 1555 | b->yy_is_interactive = 0; 1556 | b->yy_at_bol = 1; 1557 | b->yy_fill_buffer = 0; 1558 | b->yy_buffer_status = YY_BUFFER_NEW; 1559 | 1560 | yy_switch_to_buffer( b ); 1561 | 1562 | return b; 1563 | } 1564 | 1565 | /** Setup the input buffer state to scan a string. The next call to yylex() will 1566 | * scan from a @e copy of @a str. 1567 | * @param yystr a NUL-terminated string to scan 1568 | * 1569 | * @return the newly allocated buffer state object. 1570 | * @note If you want to scan bytes that may contain NUL values, then use 1571 | * yy_scan_bytes() instead. 1572 | */ 1573 | YY_BUFFER_STATE yy_scan_string (const char * yystr ) 1574 | { 1575 | 1576 | return yy_scan_bytes( yystr, (int) strlen(yystr) ); 1577 | } 1578 | 1579 | /** Setup the input buffer state to scan the given bytes. The next call to yylex() will 1580 | * scan from a @e copy of @a bytes. 1581 | * @param yybytes the byte buffer to scan 1582 | * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. 1583 | * 1584 | * @return the newly allocated buffer state object. 1585 | */ 1586 | YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) 1587 | { 1588 | YY_BUFFER_STATE b; 1589 | char *buf; 1590 | yy_size_t n; 1591 | int i; 1592 | 1593 | /* Get memory for full buffer, including space for trailing EOB's. */ 1594 | n = (yy_size_t) (_yybytes_len + 2); 1595 | buf = (char *) yyalloc( n ); 1596 | if ( ! buf ) 1597 | YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); 1598 | 1599 | for ( i = 0; i < _yybytes_len; ++i ) 1600 | buf[i] = yybytes[i]; 1601 | 1602 | buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; 1603 | 1604 | b = yy_scan_buffer( buf, n ); 1605 | if ( ! b ) 1606 | YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); 1607 | 1608 | /* It's okay to grow etc. this buffer, and we should throw it 1609 | * away when we're done. 1610 | */ 1611 | b->yy_is_our_buffer = 1; 1612 | 1613 | return b; 1614 | } 1615 | 1616 | #ifndef YY_EXIT_FAILURE 1617 | #define YY_EXIT_FAILURE 2 1618 | #endif 1619 | 1620 | static void yynoreturn yy_fatal_error (const char* msg ) 1621 | { 1622 | fprintf( stderr, "%s\n", msg ); 1623 | exit( YY_EXIT_FAILURE ); 1624 | } 1625 | 1626 | /* Redefine yyless() so it works in section 3 code. */ 1627 | 1628 | #undef yyless 1629 | #define yyless(n) \ 1630 | do \ 1631 | { \ 1632 | /* Undo effects of setting up yytext. */ \ 1633 | int yyless_macro_arg = (n); \ 1634 | YY_LESS_LINENO(yyless_macro_arg);\ 1635 | yytext[yyleng] = (yy_hold_char); \ 1636 | (yy_c_buf_p) = yytext + yyless_macro_arg; \ 1637 | (yy_hold_char) = *(yy_c_buf_p); \ 1638 | *(yy_c_buf_p) = '\0'; \ 1639 | yyleng = yyless_macro_arg; \ 1640 | } \ 1641 | while ( 0 ) 1642 | 1643 | /* Accessor methods (get/set functions) to struct members. */ 1644 | 1645 | /** Get the current line number. 1646 | * 1647 | */ 1648 | int yyget_lineno (void) 1649 | { 1650 | 1651 | return yylineno; 1652 | } 1653 | 1654 | /** Get the input stream. 1655 | * 1656 | */ 1657 | FILE *yyget_in (void) 1658 | { 1659 | return yyin; 1660 | } 1661 | 1662 | /** Get the output stream. 1663 | * 1664 | */ 1665 | FILE *yyget_out (void) 1666 | { 1667 | return yyout; 1668 | } 1669 | 1670 | /** Get the length of the current token. 1671 | * 1672 | */ 1673 | int yyget_leng (void) 1674 | { 1675 | return yyleng; 1676 | } 1677 | 1678 | /** Get the current token. 1679 | * 1680 | */ 1681 | 1682 | char *yyget_text (void) 1683 | { 1684 | return yytext; 1685 | } 1686 | 1687 | /** Set the current line number. 1688 | * @param _line_number line number 1689 | * 1690 | */ 1691 | void yyset_lineno (int _line_number ) 1692 | { 1693 | 1694 | yylineno = _line_number; 1695 | } 1696 | 1697 | /** Set the input stream. This does not discard the current 1698 | * input buffer. 1699 | * @param _in_str A readable stream. 1700 | * 1701 | * @see yy_switch_to_buffer 1702 | */ 1703 | void yyset_in (FILE * _in_str ) 1704 | { 1705 | yyin = _in_str ; 1706 | } 1707 | 1708 | void yyset_out (FILE * _out_str ) 1709 | { 1710 | yyout = _out_str ; 1711 | } 1712 | 1713 | int yyget_debug (void) 1714 | { 1715 | return yy_flex_debug; 1716 | } 1717 | 1718 | void yyset_debug (int _bdebug ) 1719 | { 1720 | yy_flex_debug = _bdebug ; 1721 | } 1722 | 1723 | static int yy_init_globals (void) 1724 | { 1725 | /* Initialization is the same as for the non-reentrant scanner. 1726 | * This function is called from yylex_destroy(), so don't allocate here. 1727 | */ 1728 | 1729 | /* We do not touch yylineno unless the option is enabled. */ 1730 | yylineno = 1; 1731 | 1732 | (yy_buffer_stack) = NULL; 1733 | (yy_buffer_stack_top) = 0; 1734 | (yy_buffer_stack_max) = 0; 1735 | (yy_c_buf_p) = NULL; 1736 | (yy_init) = 0; 1737 | (yy_start) = 0; 1738 | 1739 | /* Defined in main.c */ 1740 | #ifdef YY_STDINIT 1741 | yyin = stdin; 1742 | yyout = stdout; 1743 | #else 1744 | yyin = NULL; 1745 | yyout = NULL; 1746 | #endif 1747 | 1748 | /* For future reference: Set errno on error, since we are called by 1749 | * yylex_init() 1750 | */ 1751 | return 0; 1752 | } 1753 | 1754 | /* yylex_destroy is for both reentrant and non-reentrant scanners. */ 1755 | int yylex_destroy (void) 1756 | { 1757 | 1758 | /* Pop the buffer stack, destroying each element. */ 1759 | while(YY_CURRENT_BUFFER){ 1760 | yy_delete_buffer( YY_CURRENT_BUFFER ); 1761 | YY_CURRENT_BUFFER_LVALUE = NULL; 1762 | yypop_buffer_state(); 1763 | } 1764 | 1765 | /* Destroy the stack itself. */ 1766 | yyfree((yy_buffer_stack) ); 1767 | (yy_buffer_stack) = NULL; 1768 | 1769 | /* Reset the globals. This is important in a non-reentrant scanner so the next time 1770 | * yylex() is called, initialization will occur. */ 1771 | yy_init_globals( ); 1772 | 1773 | return 0; 1774 | } 1775 | 1776 | /* 1777 | * Internal utility routines. 1778 | */ 1779 | 1780 | #ifndef yytext_ptr 1781 | static void yy_flex_strncpy (char* s1, const char * s2, int n ) 1782 | { 1783 | 1784 | int i; 1785 | for ( i = 0; i < n; ++i ) 1786 | s1[i] = s2[i]; 1787 | } 1788 | #endif 1789 | 1790 | #ifdef YY_NEED_STRLEN 1791 | static int yy_flex_strlen (const char * s ) 1792 | { 1793 | int n; 1794 | for ( n = 0; s[n]; ++n ) 1795 | ; 1796 | 1797 | return n; 1798 | } 1799 | #endif 1800 | 1801 | void *yyalloc (yy_size_t size ) 1802 | { 1803 | return malloc(size); 1804 | } 1805 | 1806 | void *yyrealloc (void * ptr, yy_size_t size ) 1807 | { 1808 | 1809 | /* The cast to (char *) in the following accommodates both 1810 | * implementations that use char* generic pointers, and those 1811 | * that use void* generic pointers. It works with the latter 1812 | * because both ANSI C and C++ allow castless assignment from 1813 | * any pointer type to void*, and deal with argument conversions 1814 | * as though doing an assignment. 1815 | */ 1816 | return realloc(ptr, size); 1817 | } 1818 | 1819 | void yyfree (void * ptr ) 1820 | { 1821 | free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ 1822 | } 1823 | 1824 | #define YYTABLES_NAME "yytables" 1825 | 1826 | #line 18 "scanner.lex" 1827 | -------------------------------------------------------------------------------- /parser.tab.cpp: -------------------------------------------------------------------------------- 1 | /* A Bison parser, made by GNU Bison 3.5.1. */ 2 | 3 | /* Bison implementation for Yacc-like parsers in C 4 | 5 | Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, 6 | 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 3 of the License, or 11 | (at your option) 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, see . */ 20 | 21 | /* As a special exception, you may create a larger work that contains 22 | part or all of the Bison parser skeleton and distribute that work 23 | under terms of your choice, so long as that work isn't itself a 24 | parser generator using the skeleton or a modified version thereof 25 | as a parser skeleton. Alternatively, if you modify or redistribute 26 | the parser skeleton itself, you may (at your option) remove this 27 | special exception, which will cause the skeleton and the resulting 28 | Bison output files to be licensed under the GNU General Public 29 | License without this special exception. 30 | 31 | This special exception was added by the Free Software Foundation in 32 | version 2.2 of Bison. */ 33 | 34 | /* C LALR(1) parser skeleton written by Richard Stallman, by 35 | simplifying the original so-called "semantic" parser. */ 36 | 37 | /* All symbols defined below should begin with yy or YY, to avoid 38 | infringing on user name space. This should be done even for local 39 | variables, as they might otherwise be expanded by user macros. 40 | There are some unavoidable exceptions within include files to 41 | define necessary library symbols; they are noted "INFRINGES ON 42 | USER NAME SPACE" below. */ 43 | 44 | /* Undocumented macros, especially those whose name start with YY_, 45 | are private implementation details. Do not rely on them. */ 46 | 47 | /* Identify Bison output. */ 48 | #define YYBISON 1 49 | 50 | /* Bison version. */ 51 | #define YYBISON_VERSION "3.5.1" 52 | 53 | /* Skeleton name. */ 54 | #define YYSKELETON_NAME "yacc.c" 55 | 56 | /* Pure parsers. */ 57 | #define YYPURE 0 58 | 59 | /* Push parsers. */ 60 | #define YYPUSH 0 61 | 62 | /* Pull parsers. */ 63 | #define YYPULL 1 64 | 65 | 66 | 67 | 68 | /* First part of user prologue. */ 69 | #line 1 "parser.ypp" 70 | 71 | #include 72 | #include 73 | #include "nodes/node.h" 74 | #include "nodes/minusnode.h" 75 | #include "nodes/plusnode.h" 76 | #include "nodes/multnode.h" 77 | #include "nodes/divnode.h" 78 | #include "nodes/expnode.h" 79 | #include "nodes/integernode.h" 80 | #include "nodes/floatnode.h" 81 | #include "nodes/programnode.h" 82 | #include "nodes/statementnode.h" 83 | #include "scanner.c" 84 | 85 | using namespace std; 86 | extern "C" int yylex(void); 87 | extern int yylineno; 88 | 89 | void yyerror(char *s) { 90 | cerr << s << endl; 91 | } 92 | 93 | ProgramNode *program; 94 | 95 | #line 96 "parser.tab.cpp" 96 | 97 | # ifndef YY_CAST 98 | # ifdef __cplusplus 99 | # define YY_CAST(Type, Val) static_cast (Val) 100 | # define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) 101 | # else 102 | # define YY_CAST(Type, Val) ((Type) (Val)) 103 | # define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) 104 | # endif 105 | # endif 106 | # ifndef YY_NULLPTR 107 | # if defined __cplusplus 108 | # if 201103L <= __cplusplus 109 | # define YY_NULLPTR nullptr 110 | # else 111 | # define YY_NULLPTR 0 112 | # endif 113 | # else 114 | # define YY_NULLPTR ((void*)0) 115 | # endif 116 | # endif 117 | 118 | /* Enabling verbose error messages. */ 119 | #ifdef YYERROR_VERBOSE 120 | # undef YYERROR_VERBOSE 121 | # define YYERROR_VERBOSE 1 122 | #else 123 | # define YYERROR_VERBOSE 0 124 | #endif 125 | 126 | 127 | /* Debug traces. */ 128 | #ifndef YYDEBUG 129 | # define YYDEBUG 0 130 | #endif 131 | #if YYDEBUG 132 | extern int yydebug; 133 | #endif 134 | 135 | /* Token type. */ 136 | #ifndef YYTOKENTYPE 137 | # define YYTOKENTYPE 138 | enum yytokentype 139 | { 140 | INTEGER_LITERAL = 258, 141 | FLOAT_LITERAL = 259, 142 | SEMI = 260, 143 | PLUS = 261, 144 | MINUS = 262, 145 | MULT = 263, 146 | DIV = 264 147 | }; 148 | #endif 149 | 150 | /* Value type. */ 151 | #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 152 | union YYSTYPE 153 | { 154 | #line 27 "parser.ypp" 155 | 156 | int intVal; 157 | float floatVal; 158 | class Node *node; 159 | class ExpNode *expNode; 160 | class StatementNode *statementNode; 161 | 162 | #line 163 "parser.tab.cpp" 163 | 164 | }; 165 | typedef union YYSTYPE YYSTYPE; 166 | # define YYSTYPE_IS_TRIVIAL 1 167 | # define YYSTYPE_IS_DECLARED 1 168 | #endif 169 | 170 | 171 | extern YYSTYPE yylval; 172 | 173 | int yyparse (void); 174 | 175 | 176 | 177 | 178 | 179 | #ifdef short 180 | # undef short 181 | #endif 182 | 183 | /* On compilers that do not define __PTRDIFF_MAX__ etc., make sure 184 | and (if available) are included 185 | so that the code can choose integer types of a good width. */ 186 | 187 | #ifndef __PTRDIFF_MAX__ 188 | # include /* INFRINGES ON USER NAME SPACE */ 189 | # if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ 190 | # include /* INFRINGES ON USER NAME SPACE */ 191 | # define YY_STDINT_H 192 | # endif 193 | #endif 194 | 195 | /* Narrow types that promote to a signed type and that can represent a 196 | signed or unsigned integer of at least N bits. In tables they can 197 | save space and decrease cache pressure. Promoting to a signed type 198 | helps avoid bugs in integer arithmetic. */ 199 | 200 | #ifdef __INT_LEAST8_MAX__ 201 | typedef __INT_LEAST8_TYPE__ yytype_int8; 202 | #elif defined YY_STDINT_H 203 | typedef int_least8_t yytype_int8; 204 | #else 205 | typedef signed char yytype_int8; 206 | #endif 207 | 208 | #ifdef __INT_LEAST16_MAX__ 209 | typedef __INT_LEAST16_TYPE__ yytype_int16; 210 | #elif defined YY_STDINT_H 211 | typedef int_least16_t yytype_int16; 212 | #else 213 | typedef short yytype_int16; 214 | #endif 215 | 216 | #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ 217 | typedef __UINT_LEAST8_TYPE__ yytype_uint8; 218 | #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ 219 | && UINT_LEAST8_MAX <= INT_MAX) 220 | typedef uint_least8_t yytype_uint8; 221 | #elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX 222 | typedef unsigned char yytype_uint8; 223 | #else 224 | typedef short yytype_uint8; 225 | #endif 226 | 227 | #if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ 228 | typedef __UINT_LEAST16_TYPE__ yytype_uint16; 229 | #elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ 230 | && UINT_LEAST16_MAX <= INT_MAX) 231 | typedef uint_least16_t yytype_uint16; 232 | #elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX 233 | typedef unsigned short yytype_uint16; 234 | #else 235 | typedef int yytype_uint16; 236 | #endif 237 | 238 | #ifndef YYPTRDIFF_T 239 | # if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ 240 | # define YYPTRDIFF_T __PTRDIFF_TYPE__ 241 | # define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ 242 | # elif defined PTRDIFF_MAX 243 | # ifndef ptrdiff_t 244 | # include /* INFRINGES ON USER NAME SPACE */ 245 | # endif 246 | # define YYPTRDIFF_T ptrdiff_t 247 | # define YYPTRDIFF_MAXIMUM PTRDIFF_MAX 248 | # else 249 | # define YYPTRDIFF_T long 250 | # define YYPTRDIFF_MAXIMUM LONG_MAX 251 | # endif 252 | #endif 253 | 254 | #ifndef YYSIZE_T 255 | # ifdef __SIZE_TYPE__ 256 | # define YYSIZE_T __SIZE_TYPE__ 257 | # elif defined size_t 258 | # define YYSIZE_T size_t 259 | # elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ 260 | # include /* INFRINGES ON USER NAME SPACE */ 261 | # define YYSIZE_T size_t 262 | # else 263 | # define YYSIZE_T unsigned 264 | # endif 265 | #endif 266 | 267 | #define YYSIZE_MAXIMUM \ 268 | YY_CAST (YYPTRDIFF_T, \ 269 | (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ 270 | ? YYPTRDIFF_MAXIMUM \ 271 | : YY_CAST (YYSIZE_T, -1))) 272 | 273 | #define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) 274 | 275 | /* Stored state numbers (used for stacks). */ 276 | typedef yytype_int8 yy_state_t; 277 | 278 | /* State numbers in computations. */ 279 | typedef int yy_state_fast_t; 280 | 281 | #ifndef YY_ 282 | # if defined YYENABLE_NLS && YYENABLE_NLS 283 | # if ENABLE_NLS 284 | # include /* INFRINGES ON USER NAME SPACE */ 285 | # define YY_(Msgid) dgettext ("bison-runtime", Msgid) 286 | # endif 287 | # endif 288 | # ifndef YY_ 289 | # define YY_(Msgid) Msgid 290 | # endif 291 | #endif 292 | 293 | #ifndef YY_ATTRIBUTE_PURE 294 | # if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) 295 | # define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) 296 | # else 297 | # define YY_ATTRIBUTE_PURE 298 | # endif 299 | #endif 300 | 301 | #ifndef YY_ATTRIBUTE_UNUSED 302 | # if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) 303 | # define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) 304 | # else 305 | # define YY_ATTRIBUTE_UNUSED 306 | # endif 307 | #endif 308 | 309 | /* Suppress unused-variable warnings by "using" E. */ 310 | #if ! defined lint || defined __GNUC__ 311 | # define YYUSE(E) ((void) (E)) 312 | #else 313 | # define YYUSE(E) /* empty */ 314 | #endif 315 | 316 | #if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ 317 | /* Suppress an incorrect diagnostic about yylval being uninitialized. */ 318 | # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ 319 | _Pragma ("GCC diagnostic push") \ 320 | _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ 321 | _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") 322 | # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ 323 | _Pragma ("GCC diagnostic pop") 324 | #else 325 | # define YY_INITIAL_VALUE(Value) Value 326 | #endif 327 | #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN 328 | # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN 329 | # define YY_IGNORE_MAYBE_UNINITIALIZED_END 330 | #endif 331 | #ifndef YY_INITIAL_VALUE 332 | # define YY_INITIAL_VALUE(Value) /* Nothing. */ 333 | #endif 334 | 335 | #if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ 336 | # define YY_IGNORE_USELESS_CAST_BEGIN \ 337 | _Pragma ("GCC diagnostic push") \ 338 | _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") 339 | # define YY_IGNORE_USELESS_CAST_END \ 340 | _Pragma ("GCC diagnostic pop") 341 | #endif 342 | #ifndef YY_IGNORE_USELESS_CAST_BEGIN 343 | # define YY_IGNORE_USELESS_CAST_BEGIN 344 | # define YY_IGNORE_USELESS_CAST_END 345 | #endif 346 | 347 | 348 | #define YY_ASSERT(E) ((void) (0 && (E))) 349 | 350 | #if ! defined yyoverflow || YYERROR_VERBOSE 351 | 352 | /* The parser invokes alloca or malloc; define the necessary symbols. */ 353 | 354 | # ifdef YYSTACK_USE_ALLOCA 355 | # if YYSTACK_USE_ALLOCA 356 | # ifdef __GNUC__ 357 | # define YYSTACK_ALLOC __builtin_alloca 358 | # elif defined __BUILTIN_VA_ARG_INCR 359 | # include /* INFRINGES ON USER NAME SPACE */ 360 | # elif defined _AIX 361 | # define YYSTACK_ALLOC __alloca 362 | # elif defined _MSC_VER 363 | # include /* INFRINGES ON USER NAME SPACE */ 364 | # define alloca _alloca 365 | # else 366 | # define YYSTACK_ALLOC alloca 367 | # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS 368 | # include /* INFRINGES ON USER NAME SPACE */ 369 | /* Use EXIT_SUCCESS as a witness for stdlib.h. */ 370 | # ifndef EXIT_SUCCESS 371 | # define EXIT_SUCCESS 0 372 | # endif 373 | # endif 374 | # endif 375 | # endif 376 | # endif 377 | 378 | # ifdef YYSTACK_ALLOC 379 | /* Pacify GCC's 'empty if-body' warning. */ 380 | # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) 381 | # ifndef YYSTACK_ALLOC_MAXIMUM 382 | /* The OS might guarantee only one guard page at the bottom of the stack, 383 | and a page size can be as small as 4096 bytes. So we cannot safely 384 | invoke alloca (N) if N exceeds 4096. Use a slightly smaller number 385 | to allow for a few compiler-allocated temporary stack slots. */ 386 | # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ 387 | # endif 388 | # else 389 | # define YYSTACK_ALLOC YYMALLOC 390 | # define YYSTACK_FREE YYFREE 391 | # ifndef YYSTACK_ALLOC_MAXIMUM 392 | # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM 393 | # endif 394 | # if (defined __cplusplus && ! defined EXIT_SUCCESS \ 395 | && ! ((defined YYMALLOC || defined malloc) \ 396 | && (defined YYFREE || defined free))) 397 | # include /* INFRINGES ON USER NAME SPACE */ 398 | # ifndef EXIT_SUCCESS 399 | # define EXIT_SUCCESS 0 400 | # endif 401 | # endif 402 | # ifndef YYMALLOC 403 | # define YYMALLOC malloc 404 | # if ! defined malloc && ! defined EXIT_SUCCESS 405 | void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ 406 | # endif 407 | # endif 408 | # ifndef YYFREE 409 | # define YYFREE free 410 | # if ! defined free && ! defined EXIT_SUCCESS 411 | void free (void *); /* INFRINGES ON USER NAME SPACE */ 412 | # endif 413 | # endif 414 | # endif 415 | #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ 416 | 417 | 418 | #if (! defined yyoverflow \ 419 | && (! defined __cplusplus \ 420 | || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) 421 | 422 | /* A type that is properly aligned for any stack member. */ 423 | union yyalloc 424 | { 425 | yy_state_t yyss_alloc; 426 | YYSTYPE yyvs_alloc; 427 | }; 428 | 429 | /* The size of the maximum gap between one aligned stack and the next. */ 430 | # define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) 431 | 432 | /* The size of an array large to enough to hold all stacks, each with 433 | N elements. */ 434 | # define YYSTACK_BYTES(N) \ 435 | ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ 436 | + YYSTACK_GAP_MAXIMUM) 437 | 438 | # define YYCOPY_NEEDED 1 439 | 440 | /* Relocate STACK from its old location to the new one. The 441 | local variables YYSIZE and YYSTACKSIZE give the old and new number of 442 | elements in the stack, and YYPTR gives the new location of the 443 | stack. Advance YYPTR to a properly aligned location for the next 444 | stack. */ 445 | # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ 446 | do \ 447 | { \ 448 | YYPTRDIFF_T yynewbytes; \ 449 | YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ 450 | Stack = &yyptr->Stack_alloc; \ 451 | yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ 452 | yyptr += yynewbytes / YYSIZEOF (*yyptr); \ 453 | } \ 454 | while (0) 455 | 456 | #endif 457 | 458 | #if defined YYCOPY_NEEDED && YYCOPY_NEEDED 459 | /* Copy COUNT objects from SRC to DST. The source and destination do 460 | not overlap. */ 461 | # ifndef YYCOPY 462 | # if defined __GNUC__ && 1 < __GNUC__ 463 | # define YYCOPY(Dst, Src, Count) \ 464 | __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) 465 | # else 466 | # define YYCOPY(Dst, Src, Count) \ 467 | do \ 468 | { \ 469 | YYPTRDIFF_T yyi; \ 470 | for (yyi = 0; yyi < (Count); yyi++) \ 471 | (Dst)[yyi] = (Src)[yyi]; \ 472 | } \ 473 | while (0) 474 | # endif 475 | # endif 476 | #endif /* !YYCOPY_NEEDED */ 477 | 478 | /* YYFINAL -- State number of the termination state. */ 479 | #define YYFINAL 2 480 | /* YYLAST -- Last index in YYTABLE. */ 481 | #define YYLAST 15 482 | 483 | /* YYNTOKENS -- Number of terminals. */ 484 | #define YYNTOKENS 10 485 | /* YYNNTS -- Number of nonterminals. */ 486 | #define YYNNTS 4 487 | /* YYNRULES -- Number of rules. */ 488 | #define YYNRULES 10 489 | /* YYNSTATES -- Number of states. */ 490 | #define YYNSTATES 16 491 | 492 | #define YYUNDEFTOK 2 493 | #define YYMAXUTOK 264 494 | 495 | 496 | /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM 497 | as returned by yylex, with out-of-bounds checking. */ 498 | #define YYTRANSLATE(YYX) \ 499 | (0 <= (YYX) && (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) 500 | 501 | /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM 502 | as returned by yylex. */ 503 | static const yytype_int8 yytranslate[] = 504 | { 505 | 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 506 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 507 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 508 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 509 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 510 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 511 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 512 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 513 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 514 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 515 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 516 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 517 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 518 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 519 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 520 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 521 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 522 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 523 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 524 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 525 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 526 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 527 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 528 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 529 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 530 | 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 531 | 5, 6, 7, 8, 9 532 | }; 533 | 534 | #if YYDEBUG 535 | /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ 536 | static const yytype_int8 yyrline[] = 537 | { 538 | 0, 48, 48, 49, 52, 56, 57, 58, 59, 60, 539 | 61 540 | }; 541 | #endif 542 | 543 | #if YYDEBUG || YYERROR_VERBOSE || 0 544 | /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. 545 | First, the terminals, then, starting at YYNTOKENS, nonterminals. */ 546 | static const char *const yytname[] = 547 | { 548 | "$end", "error", "$undefined", "INTEGER_LITERAL", "FLOAT_LITERAL", 549 | "SEMI", "PLUS", "MINUS", "MULT", "DIV", "$accept", "program", 550 | "statement", "exp", YY_NULLPTR 551 | }; 552 | #endif 553 | 554 | # ifdef YYPRINT 555 | /* YYTOKNUM[NUM] -- (External) token number corresponding to the 556 | (internal) symbol number NUM (which must be that of a token). */ 557 | static const yytype_int16 yytoknum[] = 558 | { 559 | 0, 256, 257, 258, 259, 260, 261, 262, 263, 264 560 | }; 561 | # endif 562 | 563 | #define YYPACT_NINF (-6) 564 | 565 | #define yypact_value_is_default(Yyn) \ 566 | ((Yyn) == YYPACT_NINF) 567 | 568 | #define YYTABLE_NINF (-1) 569 | 570 | #define yytable_value_is_error(Yyn) \ 571 | 0 572 | 573 | /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing 574 | STATE-NUM. */ 575 | static const yytype_int8 yypact[] = 576 | { 577 | -6, 5, -6, -6, -6, -6, -5, -6, 3, 3, 578 | 3, 3, 6, 6, -6, -6 579 | }; 580 | 581 | /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. 582 | Performed when YYTABLE does not specify something else to do. Zero 583 | means the default is an error. */ 584 | static const yytype_int8 yydefact[] = 585 | { 586 | 2, 0, 1, 5, 6, 3, 0, 4, 0, 0, 587 | 0, 0, 7, 8, 9, 10 588 | }; 589 | 590 | /* YYPGOTO[NTERM-NUM]. */ 591 | static const yytype_int8 yypgoto[] = 592 | { 593 | -6, -6, -6, 2 594 | }; 595 | 596 | /* YYDEFGOTO[NTERM-NUM]. */ 597 | static const yytype_int8 yydefgoto[] = 598 | { 599 | -1, 1, 5, 6 600 | }; 601 | 602 | /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If 603 | positive, shift that token. If negative, reduce the rule whose 604 | number is the opposite. If YYTABLE_NINF, syntax error. */ 605 | static const yytype_int8 yytable[] = 606 | { 607 | 7, 8, 9, 10, 11, 2, 3, 4, 3, 4, 608 | 12, 13, 14, 15, 10, 11 609 | }; 610 | 611 | static const yytype_int8 yycheck[] = 612 | { 613 | 5, 6, 7, 8, 9, 0, 3, 4, 3, 4, 614 | 8, 9, 10, 11, 8, 9 615 | }; 616 | 617 | /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing 618 | symbol of state STATE-NUM. */ 619 | static const yytype_int8 yystos[] = 620 | { 621 | 0, 11, 0, 3, 4, 12, 13, 5, 6, 7, 622 | 8, 9, 13, 13, 13, 13 623 | }; 624 | 625 | /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ 626 | static const yytype_int8 yyr1[] = 627 | { 628 | 0, 10, 11, 11, 12, 13, 13, 13, 13, 13, 629 | 13 630 | }; 631 | 632 | /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ 633 | static const yytype_int8 yyr2[] = 634 | { 635 | 0, 2, 0, 2, 2, 1, 1, 3, 3, 3, 636 | 3 637 | }; 638 | 639 | 640 | #define yyerrok (yyerrstatus = 0) 641 | #define yyclearin (yychar = YYEMPTY) 642 | #define YYEMPTY (-2) 643 | #define YYEOF 0 644 | 645 | #define YYACCEPT goto yyacceptlab 646 | #define YYABORT goto yyabortlab 647 | #define YYERROR goto yyerrorlab 648 | 649 | 650 | #define YYRECOVERING() (!!yyerrstatus) 651 | 652 | #define YYBACKUP(Token, Value) \ 653 | do \ 654 | if (yychar == YYEMPTY) \ 655 | { \ 656 | yychar = (Token); \ 657 | yylval = (Value); \ 658 | YYPOPSTACK (yylen); \ 659 | yystate = *yyssp; \ 660 | goto yybackup; \ 661 | } \ 662 | else \ 663 | { \ 664 | yyerror (YY_("syntax error: cannot back up")); \ 665 | YYERROR; \ 666 | } \ 667 | while (0) 668 | 669 | /* Error token number */ 670 | #define YYTERROR 1 671 | #define YYERRCODE 256 672 | 673 | 674 | 675 | /* Enable debugging if requested. */ 676 | #if YYDEBUG 677 | 678 | # ifndef YYFPRINTF 679 | # include /* INFRINGES ON USER NAME SPACE */ 680 | # define YYFPRINTF fprintf 681 | # endif 682 | 683 | # define YYDPRINTF(Args) \ 684 | do { \ 685 | if (yydebug) \ 686 | YYFPRINTF Args; \ 687 | } while (0) 688 | 689 | /* This macro is provided for backward compatibility. */ 690 | #ifndef YY_LOCATION_PRINT 691 | # define YY_LOCATION_PRINT(File, Loc) ((void) 0) 692 | #endif 693 | 694 | 695 | # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ 696 | do { \ 697 | if (yydebug) \ 698 | { \ 699 | YYFPRINTF (stderr, "%s ", Title); \ 700 | yy_symbol_print (stderr, \ 701 | Type, Value); \ 702 | YYFPRINTF (stderr, "\n"); \ 703 | } \ 704 | } while (0) 705 | 706 | 707 | /*-----------------------------------. 708 | | Print this symbol's value on YYO. | 709 | `-----------------------------------*/ 710 | 711 | static void 712 | yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) 713 | { 714 | FILE *yyoutput = yyo; 715 | YYUSE (yyoutput); 716 | if (!yyvaluep) 717 | return; 718 | # ifdef YYPRINT 719 | if (yytype < YYNTOKENS) 720 | YYPRINT (yyo, yytoknum[yytype], *yyvaluep); 721 | # endif 722 | YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN 723 | YYUSE (yytype); 724 | YY_IGNORE_MAYBE_UNINITIALIZED_END 725 | } 726 | 727 | 728 | /*---------------------------. 729 | | Print this symbol on YYO. | 730 | `---------------------------*/ 731 | 732 | static void 733 | yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) 734 | { 735 | YYFPRINTF (yyo, "%s %s (", 736 | yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); 737 | 738 | yy_symbol_value_print (yyo, yytype, yyvaluep); 739 | YYFPRINTF (yyo, ")"); 740 | } 741 | 742 | /*------------------------------------------------------------------. 743 | | yy_stack_print -- Print the state stack from its BOTTOM up to its | 744 | | TOP (included). | 745 | `------------------------------------------------------------------*/ 746 | 747 | static void 748 | yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) 749 | { 750 | YYFPRINTF (stderr, "Stack now"); 751 | for (; yybottom <= yytop; yybottom++) 752 | { 753 | int yybot = *yybottom; 754 | YYFPRINTF (stderr, " %d", yybot); 755 | } 756 | YYFPRINTF (stderr, "\n"); 757 | } 758 | 759 | # define YY_STACK_PRINT(Bottom, Top) \ 760 | do { \ 761 | if (yydebug) \ 762 | yy_stack_print ((Bottom), (Top)); \ 763 | } while (0) 764 | 765 | 766 | /*------------------------------------------------. 767 | | Report that the YYRULE is going to be reduced. | 768 | `------------------------------------------------*/ 769 | 770 | static void 771 | yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, int yyrule) 772 | { 773 | int yylno = yyrline[yyrule]; 774 | int yynrhs = yyr2[yyrule]; 775 | int yyi; 776 | YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", 777 | yyrule - 1, yylno); 778 | /* The symbols being reduced. */ 779 | for (yyi = 0; yyi < yynrhs; yyi++) 780 | { 781 | YYFPRINTF (stderr, " $%d = ", yyi + 1); 782 | yy_symbol_print (stderr, 783 | yystos[+yyssp[yyi + 1 - yynrhs]], 784 | &yyvsp[(yyi + 1) - (yynrhs)] 785 | ); 786 | YYFPRINTF (stderr, "\n"); 787 | } 788 | } 789 | 790 | # define YY_REDUCE_PRINT(Rule) \ 791 | do { \ 792 | if (yydebug) \ 793 | yy_reduce_print (yyssp, yyvsp, Rule); \ 794 | } while (0) 795 | 796 | /* Nonzero means print parse trace. It is left uninitialized so that 797 | multiple parsers can coexist. */ 798 | int yydebug; 799 | #else /* !YYDEBUG */ 800 | # define YYDPRINTF(Args) 801 | # define YY_SYMBOL_PRINT(Title, Type, Value, Location) 802 | # define YY_STACK_PRINT(Bottom, Top) 803 | # define YY_REDUCE_PRINT(Rule) 804 | #endif /* !YYDEBUG */ 805 | 806 | 807 | /* YYINITDEPTH -- initial size of the parser's stacks. */ 808 | #ifndef YYINITDEPTH 809 | # define YYINITDEPTH 200 810 | #endif 811 | 812 | /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only 813 | if the built-in stack extension method is used). 814 | 815 | Do not make this value too large; the results are undefined if 816 | YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) 817 | evaluated with infinite-precision integer arithmetic. */ 818 | 819 | #ifndef YYMAXDEPTH 820 | # define YYMAXDEPTH 10000 821 | #endif 822 | 823 | 824 | #if YYERROR_VERBOSE 825 | 826 | # ifndef yystrlen 827 | # if defined __GLIBC__ && defined _STRING_H 828 | # define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) 829 | # else 830 | /* Return the length of YYSTR. */ 831 | static YYPTRDIFF_T 832 | yystrlen (const char *yystr) 833 | { 834 | YYPTRDIFF_T yylen; 835 | for (yylen = 0; yystr[yylen]; yylen++) 836 | continue; 837 | return yylen; 838 | } 839 | # endif 840 | # endif 841 | 842 | # ifndef yystpcpy 843 | # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE 844 | # define yystpcpy stpcpy 845 | # else 846 | /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in 847 | YYDEST. */ 848 | static char * 849 | yystpcpy (char *yydest, const char *yysrc) 850 | { 851 | char *yyd = yydest; 852 | const char *yys = yysrc; 853 | 854 | while ((*yyd++ = *yys++) != '\0') 855 | continue; 856 | 857 | return yyd - 1; 858 | } 859 | # endif 860 | # endif 861 | 862 | # ifndef yytnamerr 863 | /* Copy to YYRES the contents of YYSTR after stripping away unnecessary 864 | quotes and backslashes, so that it's suitable for yyerror. The 865 | heuristic is that double-quoting is unnecessary unless the string 866 | contains an apostrophe, a comma, or backslash (other than 867 | backslash-backslash). YYSTR is taken from yytname. If YYRES is 868 | null, do not copy; instead, return the length of what the result 869 | would have been. */ 870 | static YYPTRDIFF_T 871 | yytnamerr (char *yyres, const char *yystr) 872 | { 873 | if (*yystr == '"') 874 | { 875 | YYPTRDIFF_T yyn = 0; 876 | char const *yyp = yystr; 877 | 878 | for (;;) 879 | switch (*++yyp) 880 | { 881 | case '\'': 882 | case ',': 883 | goto do_not_strip_quotes; 884 | 885 | case '\\': 886 | if (*++yyp != '\\') 887 | goto do_not_strip_quotes; 888 | else 889 | goto append; 890 | 891 | append: 892 | default: 893 | if (yyres) 894 | yyres[yyn] = *yyp; 895 | yyn++; 896 | break; 897 | 898 | case '"': 899 | if (yyres) 900 | yyres[yyn] = '\0'; 901 | return yyn; 902 | } 903 | do_not_strip_quotes: ; 904 | } 905 | 906 | if (yyres) 907 | return yystpcpy (yyres, yystr) - yyres; 908 | else 909 | return yystrlen (yystr); 910 | } 911 | # endif 912 | 913 | /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message 914 | about the unexpected token YYTOKEN for the state stack whose top is 915 | YYSSP. 916 | 917 | Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is 918 | not large enough to hold the message. In that case, also set 919 | *YYMSG_ALLOC to the required number of bytes. Return 2 if the 920 | required number of bytes is too large to store. */ 921 | static int 922 | yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, 923 | yy_state_t *yyssp, int yytoken) 924 | { 925 | enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; 926 | /* Internationalized format string. */ 927 | const char *yyformat = YY_NULLPTR; 928 | /* Arguments of yyformat: reported tokens (one for the "unexpected", 929 | one per "expected"). */ 930 | char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; 931 | /* Actual size of YYARG. */ 932 | int yycount = 0; 933 | /* Cumulated lengths of YYARG. */ 934 | YYPTRDIFF_T yysize = 0; 935 | 936 | /* There are many possibilities here to consider: 937 | - If this state is a consistent state with a default action, then 938 | the only way this function was invoked is if the default action 939 | is an error action. In that case, don't check for expected 940 | tokens because there are none. 941 | - The only way there can be no lookahead present (in yychar) is if 942 | this state is a consistent state with a default action. Thus, 943 | detecting the absence of a lookahead is sufficient to determine 944 | that there is no unexpected or expected token to report. In that 945 | case, just report a simple "syntax error". 946 | - Don't assume there isn't a lookahead just because this state is a 947 | consistent state with a default action. There might have been a 948 | previous inconsistent state, consistent state with a non-default 949 | action, or user semantic action that manipulated yychar. 950 | - Of course, the expected token list depends on states to have 951 | correct lookahead information, and it depends on the parser not 952 | to perform extra reductions after fetching a lookahead from the 953 | scanner and before detecting a syntax error. Thus, state merging 954 | (from LALR or IELR) and default reductions corrupt the expected 955 | token list. However, the list is correct for canonical LR with 956 | one exception: it will still contain any token that will not be 957 | accepted due to an error action in a later state. 958 | */ 959 | if (yytoken != YYEMPTY) 960 | { 961 | int yyn = yypact[+*yyssp]; 962 | YYPTRDIFF_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); 963 | yysize = yysize0; 964 | yyarg[yycount++] = yytname[yytoken]; 965 | if (!yypact_value_is_default (yyn)) 966 | { 967 | /* Start YYX at -YYN if negative to avoid negative indexes in 968 | YYCHECK. In other words, skip the first -YYN actions for 969 | this state because they are default actions. */ 970 | int yyxbegin = yyn < 0 ? -yyn : 0; 971 | /* Stay within bounds of both yycheck and yytname. */ 972 | int yychecklim = YYLAST - yyn + 1; 973 | int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; 974 | int yyx; 975 | 976 | for (yyx = yyxbegin; yyx < yyxend; ++yyx) 977 | if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR 978 | && !yytable_value_is_error (yytable[yyx + yyn])) 979 | { 980 | if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) 981 | { 982 | yycount = 1; 983 | yysize = yysize0; 984 | break; 985 | } 986 | yyarg[yycount++] = yytname[yyx]; 987 | { 988 | YYPTRDIFF_T yysize1 989 | = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); 990 | if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) 991 | yysize = yysize1; 992 | else 993 | return 2; 994 | } 995 | } 996 | } 997 | } 998 | 999 | switch (yycount) 1000 | { 1001 | # define YYCASE_(N, S) \ 1002 | case N: \ 1003 | yyformat = S; \ 1004 | break 1005 | default: /* Avoid compiler warnings. */ 1006 | YYCASE_(0, YY_("syntax error")); 1007 | YYCASE_(1, YY_("syntax error, unexpected %s")); 1008 | YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); 1009 | YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); 1010 | YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); 1011 | YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); 1012 | # undef YYCASE_ 1013 | } 1014 | 1015 | { 1016 | /* Don't count the "%s"s in the final size, but reserve room for 1017 | the terminator. */ 1018 | YYPTRDIFF_T yysize1 = yysize + (yystrlen (yyformat) - 2 * yycount) + 1; 1019 | if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) 1020 | yysize = yysize1; 1021 | else 1022 | return 2; 1023 | } 1024 | 1025 | if (*yymsg_alloc < yysize) 1026 | { 1027 | *yymsg_alloc = 2 * yysize; 1028 | if (! (yysize <= *yymsg_alloc 1029 | && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) 1030 | *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; 1031 | return 1; 1032 | } 1033 | 1034 | /* Avoid sprintf, as that infringes on the user's name space. 1035 | Don't have undefined behavior even if the translation 1036 | produced a string with the wrong number of "%s"s. */ 1037 | { 1038 | char *yyp = *yymsg; 1039 | int yyi = 0; 1040 | while ((*yyp = *yyformat) != '\0') 1041 | if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) 1042 | { 1043 | yyp += yytnamerr (yyp, yyarg[yyi++]); 1044 | yyformat += 2; 1045 | } 1046 | else 1047 | { 1048 | ++yyp; 1049 | ++yyformat; 1050 | } 1051 | } 1052 | return 0; 1053 | } 1054 | #endif /* YYERROR_VERBOSE */ 1055 | 1056 | /*-----------------------------------------------. 1057 | | Release the memory associated to this symbol. | 1058 | `-----------------------------------------------*/ 1059 | 1060 | static void 1061 | yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) 1062 | { 1063 | YYUSE (yyvaluep); 1064 | if (!yymsg) 1065 | yymsg = "Deleting"; 1066 | YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); 1067 | 1068 | YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN 1069 | YYUSE (yytype); 1070 | YY_IGNORE_MAYBE_UNINITIALIZED_END 1071 | } 1072 | 1073 | 1074 | 1075 | 1076 | /* The lookahead symbol. */ 1077 | int yychar; 1078 | 1079 | /* The semantic value of the lookahead symbol. */ 1080 | YYSTYPE yylval; 1081 | /* Number of syntax errors so far. */ 1082 | int yynerrs; 1083 | 1084 | 1085 | /*----------. 1086 | | yyparse. | 1087 | `----------*/ 1088 | 1089 | int 1090 | yyparse (void) 1091 | { 1092 | yy_state_fast_t yystate; 1093 | /* Number of tokens to shift before error messages enabled. */ 1094 | int yyerrstatus; 1095 | 1096 | /* The stacks and their tools: 1097 | 'yyss': related to states. 1098 | 'yyvs': related to semantic values. 1099 | 1100 | Refer to the stacks through separate pointers, to allow yyoverflow 1101 | to reallocate them elsewhere. */ 1102 | 1103 | /* The state stack. */ 1104 | yy_state_t yyssa[YYINITDEPTH]; 1105 | yy_state_t *yyss; 1106 | yy_state_t *yyssp; 1107 | 1108 | /* The semantic value stack. */ 1109 | YYSTYPE yyvsa[YYINITDEPTH]; 1110 | YYSTYPE *yyvs; 1111 | YYSTYPE *yyvsp; 1112 | 1113 | YYPTRDIFF_T yystacksize; 1114 | 1115 | int yyn; 1116 | int yyresult; 1117 | /* Lookahead token as an internal (translated) token number. */ 1118 | int yytoken = 0; 1119 | /* The variables used to return semantic value and location from the 1120 | action routines. */ 1121 | YYSTYPE yyval; 1122 | 1123 | #if YYERROR_VERBOSE 1124 | /* Buffer for error messages, and its allocated size. */ 1125 | char yymsgbuf[128]; 1126 | char *yymsg = yymsgbuf; 1127 | YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; 1128 | #endif 1129 | 1130 | #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) 1131 | 1132 | /* The number of symbols on the RHS of the reduced rule. 1133 | Keep to zero when no symbol should be popped. */ 1134 | int yylen = 0; 1135 | 1136 | yyssp = yyss = yyssa; 1137 | yyvsp = yyvs = yyvsa; 1138 | yystacksize = YYINITDEPTH; 1139 | 1140 | YYDPRINTF ((stderr, "Starting parse\n")); 1141 | 1142 | yystate = 0; 1143 | yyerrstatus = 0; 1144 | yynerrs = 0; 1145 | yychar = YYEMPTY; /* Cause a token to be read. */ 1146 | goto yysetstate; 1147 | 1148 | 1149 | /*------------------------------------------------------------. 1150 | | yynewstate -- push a new state, which is found in yystate. | 1151 | `------------------------------------------------------------*/ 1152 | yynewstate: 1153 | /* In all cases, when you get here, the value and location stacks 1154 | have just been pushed. So pushing a state here evens the stacks. */ 1155 | yyssp++; 1156 | 1157 | 1158 | /*--------------------------------------------------------------------. 1159 | | yysetstate -- set current state (the top of the stack) to yystate. | 1160 | `--------------------------------------------------------------------*/ 1161 | yysetstate: 1162 | YYDPRINTF ((stderr, "Entering state %d\n", yystate)); 1163 | YY_ASSERT (0 <= yystate && yystate < YYNSTATES); 1164 | YY_IGNORE_USELESS_CAST_BEGIN 1165 | *yyssp = YY_CAST (yy_state_t, yystate); 1166 | YY_IGNORE_USELESS_CAST_END 1167 | 1168 | if (yyss + yystacksize - 1 <= yyssp) 1169 | #if !defined yyoverflow && !defined YYSTACK_RELOCATE 1170 | goto yyexhaustedlab; 1171 | #else 1172 | { 1173 | /* Get the current used size of the three stacks, in elements. */ 1174 | YYPTRDIFF_T yysize = yyssp - yyss + 1; 1175 | 1176 | # if defined yyoverflow 1177 | { 1178 | /* Give user a chance to reallocate the stack. Use copies of 1179 | these so that the &'s don't force the real ones into 1180 | memory. */ 1181 | yy_state_t *yyss1 = yyss; 1182 | YYSTYPE *yyvs1 = yyvs; 1183 | 1184 | /* Each stack pointer address is followed by the size of the 1185 | data in use in that stack, in bytes. This used to be a 1186 | conditional around just the two extra args, but that might 1187 | be undefined if yyoverflow is a macro. */ 1188 | yyoverflow (YY_("memory exhausted"), 1189 | &yyss1, yysize * YYSIZEOF (*yyssp), 1190 | &yyvs1, yysize * YYSIZEOF (*yyvsp), 1191 | &yystacksize); 1192 | yyss = yyss1; 1193 | yyvs = yyvs1; 1194 | } 1195 | # else /* defined YYSTACK_RELOCATE */ 1196 | /* Extend the stack our own way. */ 1197 | if (YYMAXDEPTH <= yystacksize) 1198 | goto yyexhaustedlab; 1199 | yystacksize *= 2; 1200 | if (YYMAXDEPTH < yystacksize) 1201 | yystacksize = YYMAXDEPTH; 1202 | 1203 | { 1204 | yy_state_t *yyss1 = yyss; 1205 | union yyalloc *yyptr = 1206 | YY_CAST (union yyalloc *, 1207 | YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); 1208 | if (! yyptr) 1209 | goto yyexhaustedlab; 1210 | YYSTACK_RELOCATE (yyss_alloc, yyss); 1211 | YYSTACK_RELOCATE (yyvs_alloc, yyvs); 1212 | # undef YYSTACK_RELOCATE 1213 | if (yyss1 != yyssa) 1214 | YYSTACK_FREE (yyss1); 1215 | } 1216 | # endif 1217 | 1218 | yyssp = yyss + yysize - 1; 1219 | yyvsp = yyvs + yysize - 1; 1220 | 1221 | YY_IGNORE_USELESS_CAST_BEGIN 1222 | YYDPRINTF ((stderr, "Stack size increased to %ld\n", 1223 | YY_CAST (long, yystacksize))); 1224 | YY_IGNORE_USELESS_CAST_END 1225 | 1226 | if (yyss + yystacksize - 1 <= yyssp) 1227 | YYABORT; 1228 | } 1229 | #endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ 1230 | 1231 | if (yystate == YYFINAL) 1232 | YYACCEPT; 1233 | 1234 | goto yybackup; 1235 | 1236 | 1237 | /*-----------. 1238 | | yybackup. | 1239 | `-----------*/ 1240 | yybackup: 1241 | /* Do appropriate processing given the current state. Read a 1242 | lookahead token if we need one and don't already have one. */ 1243 | 1244 | /* First try to decide what to do without reference to lookahead token. */ 1245 | yyn = yypact[yystate]; 1246 | if (yypact_value_is_default (yyn)) 1247 | goto yydefault; 1248 | 1249 | /* Not known => get a lookahead token if don't already have one. */ 1250 | 1251 | /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ 1252 | if (yychar == YYEMPTY) 1253 | { 1254 | YYDPRINTF ((stderr, "Reading a token: ")); 1255 | yychar = yylex (); 1256 | } 1257 | 1258 | if (yychar <= YYEOF) 1259 | { 1260 | yychar = yytoken = YYEOF; 1261 | YYDPRINTF ((stderr, "Now at end of input.\n")); 1262 | } 1263 | else 1264 | { 1265 | yytoken = YYTRANSLATE (yychar); 1266 | YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); 1267 | } 1268 | 1269 | /* If the proper action on seeing token YYTOKEN is to reduce or to 1270 | detect an error, take that action. */ 1271 | yyn += yytoken; 1272 | if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) 1273 | goto yydefault; 1274 | yyn = yytable[yyn]; 1275 | if (yyn <= 0) 1276 | { 1277 | if (yytable_value_is_error (yyn)) 1278 | goto yyerrlab; 1279 | yyn = -yyn; 1280 | goto yyreduce; 1281 | } 1282 | 1283 | /* Count tokens shifted since error; after three, turn off error 1284 | status. */ 1285 | if (yyerrstatus) 1286 | yyerrstatus--; 1287 | 1288 | /* Shift the lookahead token. */ 1289 | YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); 1290 | yystate = yyn; 1291 | YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN 1292 | *++yyvsp = yylval; 1293 | YY_IGNORE_MAYBE_UNINITIALIZED_END 1294 | 1295 | /* Discard the shifted token. */ 1296 | yychar = YYEMPTY; 1297 | goto yynewstate; 1298 | 1299 | 1300 | /*-----------------------------------------------------------. 1301 | | yydefault -- do the default action for the current state. | 1302 | `-----------------------------------------------------------*/ 1303 | yydefault: 1304 | yyn = yydefact[yystate]; 1305 | if (yyn == 0) 1306 | goto yyerrlab; 1307 | goto yyreduce; 1308 | 1309 | 1310 | /*-----------------------------. 1311 | | yyreduce -- do a reduction. | 1312 | `-----------------------------*/ 1313 | yyreduce: 1314 | /* yyn is the number of a rule to reduce with. */ 1315 | yylen = yyr2[yyn]; 1316 | 1317 | /* If YYLEN is nonzero, implement the default value of the action: 1318 | '$$ = $1'. 1319 | 1320 | Otherwise, the following line sets YYVAL to garbage. 1321 | This behavior is undocumented and Bison 1322 | users should not rely upon it. Assigning to YYVAL 1323 | unconditionally makes the parser a bit smaller, and it avoids a 1324 | GCC warning that YYVAL may be used uninitialized. */ 1325 | yyval = yyvsp[1-yylen]; 1326 | 1327 | 1328 | YY_REDUCE_PRINT (yyn); 1329 | switch (yyn) 1330 | { 1331 | case 2: 1332 | #line 48 "parser.ypp" 1333 | { program = new ProgramNode(yylineno); } 1334 | #line 1335 "parser.tab.cpp" 1335 | break; 1336 | 1337 | case 3: 1338 | #line 49 "parser.ypp" 1339 | { assert(program); program->addStatement((yyvsp[0].statementNode)); } 1340 | #line 1341 "parser.tab.cpp" 1341 | break; 1342 | 1343 | case 4: 1344 | #line 52 "parser.ypp" 1345 | { (yyval.statementNode) = new StatementNode(yylineno, (yyvsp[-1].expNode)); } 1346 | #line 1347 "parser.tab.cpp" 1347 | break; 1348 | 1349 | case 5: 1350 | #line 56 "parser.ypp" 1351 | { (yyval.expNode) = new IntegerNode(yylineno, (yyvsp[0].intVal)); } 1352 | #line 1353 "parser.tab.cpp" 1353 | break; 1354 | 1355 | case 6: 1356 | #line 57 "parser.ypp" 1357 | { (yyval.expNode) = new FloatNode(yylineno, (yyvsp[0].floatVal)); } 1358 | #line 1359 "parser.tab.cpp" 1359 | break; 1360 | 1361 | case 7: 1362 | #line 58 "parser.ypp" 1363 | { (yyval.expNode) = new PlusNode(yylineno, (yyvsp[-2].expNode), (yyvsp[0].expNode)); } 1364 | #line 1365 "parser.tab.cpp" 1365 | break; 1366 | 1367 | case 8: 1368 | #line 59 "parser.ypp" 1369 | { (yyval.expNode) = new MinusNode(yylineno, (yyvsp[-2].expNode), (yyvsp[0].expNode)); } 1370 | #line 1371 "parser.tab.cpp" 1371 | break; 1372 | 1373 | case 9: 1374 | #line 60 "parser.ypp" 1375 | { (yyval.expNode) = new MultNode(yylineno, (yyvsp[-2].expNode), (yyvsp[0].expNode)); } 1376 | #line 1377 "parser.tab.cpp" 1377 | break; 1378 | 1379 | case 10: 1380 | #line 61 "parser.ypp" 1381 | { (yyval.expNode) = new DivNode(yylineno, (yyvsp[-2].expNode), (yyvsp[0].expNode)); } 1382 | #line 1383 "parser.tab.cpp" 1383 | break; 1384 | 1385 | 1386 | #line 1387 "parser.tab.cpp" 1387 | 1388 | default: break; 1389 | } 1390 | /* User semantic actions sometimes alter yychar, and that requires 1391 | that yytoken be updated with the new translation. We take the 1392 | approach of translating immediately before every use of yytoken. 1393 | One alternative is translating here after every semantic action, 1394 | but that translation would be missed if the semantic action invokes 1395 | YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or 1396 | if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an 1397 | incorrect destructor might then be invoked immediately. In the 1398 | case of YYERROR or YYBACKUP, subsequent parser actions might lead 1399 | to an incorrect destructor call or verbose syntax error message 1400 | before the lookahead is translated. */ 1401 | YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); 1402 | 1403 | YYPOPSTACK (yylen); 1404 | yylen = 0; 1405 | YY_STACK_PRINT (yyss, yyssp); 1406 | 1407 | *++yyvsp = yyval; 1408 | 1409 | /* Now 'shift' the result of the reduction. Determine what state 1410 | that goes to, based on the state we popped back to and the rule 1411 | number reduced by. */ 1412 | { 1413 | const int yylhs = yyr1[yyn] - YYNTOKENS; 1414 | const int yyi = yypgoto[yylhs] + *yyssp; 1415 | yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp 1416 | ? yytable[yyi] 1417 | : yydefgoto[yylhs]); 1418 | } 1419 | 1420 | goto yynewstate; 1421 | 1422 | 1423 | /*--------------------------------------. 1424 | | yyerrlab -- here on detecting error. | 1425 | `--------------------------------------*/ 1426 | yyerrlab: 1427 | /* Make sure we have latest lookahead translation. See comments at 1428 | user semantic actions for why this is necessary. */ 1429 | yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); 1430 | 1431 | /* If not already recovering from an error, report this error. */ 1432 | if (!yyerrstatus) 1433 | { 1434 | ++yynerrs; 1435 | #if ! YYERROR_VERBOSE 1436 | yyerror (YY_("syntax error")); 1437 | #else 1438 | # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ 1439 | yyssp, yytoken) 1440 | { 1441 | char const *yymsgp = YY_("syntax error"); 1442 | int yysyntax_error_status; 1443 | yysyntax_error_status = YYSYNTAX_ERROR; 1444 | if (yysyntax_error_status == 0) 1445 | yymsgp = yymsg; 1446 | else if (yysyntax_error_status == 1) 1447 | { 1448 | if (yymsg != yymsgbuf) 1449 | YYSTACK_FREE (yymsg); 1450 | yymsg = YY_CAST (char *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); 1451 | if (!yymsg) 1452 | { 1453 | yymsg = yymsgbuf; 1454 | yymsg_alloc = sizeof yymsgbuf; 1455 | yysyntax_error_status = 2; 1456 | } 1457 | else 1458 | { 1459 | yysyntax_error_status = YYSYNTAX_ERROR; 1460 | yymsgp = yymsg; 1461 | } 1462 | } 1463 | yyerror (yymsgp); 1464 | if (yysyntax_error_status == 2) 1465 | goto yyexhaustedlab; 1466 | } 1467 | # undef YYSYNTAX_ERROR 1468 | #endif 1469 | } 1470 | 1471 | 1472 | 1473 | if (yyerrstatus == 3) 1474 | { 1475 | /* If just tried and failed to reuse lookahead token after an 1476 | error, discard it. */ 1477 | 1478 | if (yychar <= YYEOF) 1479 | { 1480 | /* Return failure if at end of input. */ 1481 | if (yychar == YYEOF) 1482 | YYABORT; 1483 | } 1484 | else 1485 | { 1486 | yydestruct ("Error: discarding", 1487 | yytoken, &yylval); 1488 | yychar = YYEMPTY; 1489 | } 1490 | } 1491 | 1492 | /* Else will try to reuse lookahead token after shifting the error 1493 | token. */ 1494 | goto yyerrlab1; 1495 | 1496 | 1497 | /*---------------------------------------------------. 1498 | | yyerrorlab -- error raised explicitly by YYERROR. | 1499 | `---------------------------------------------------*/ 1500 | yyerrorlab: 1501 | /* Pacify compilers when the user code never invokes YYERROR and the 1502 | label yyerrorlab therefore never appears in user code. */ 1503 | if (0) 1504 | YYERROR; 1505 | 1506 | /* Do not reclaim the symbols of the rule whose action triggered 1507 | this YYERROR. */ 1508 | YYPOPSTACK (yylen); 1509 | yylen = 0; 1510 | YY_STACK_PRINT (yyss, yyssp); 1511 | yystate = *yyssp; 1512 | goto yyerrlab1; 1513 | 1514 | 1515 | /*-------------------------------------------------------------. 1516 | | yyerrlab1 -- common code for both syntax error and YYERROR. | 1517 | `-------------------------------------------------------------*/ 1518 | yyerrlab1: 1519 | yyerrstatus = 3; /* Each real token shifted decrements this. */ 1520 | 1521 | for (;;) 1522 | { 1523 | yyn = yypact[yystate]; 1524 | if (!yypact_value_is_default (yyn)) 1525 | { 1526 | yyn += YYTERROR; 1527 | if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) 1528 | { 1529 | yyn = yytable[yyn]; 1530 | if (0 < yyn) 1531 | break; 1532 | } 1533 | } 1534 | 1535 | /* Pop the current state because it cannot handle the error token. */ 1536 | if (yyssp == yyss) 1537 | YYABORT; 1538 | 1539 | 1540 | yydestruct ("Error: popping", 1541 | yystos[yystate], yyvsp); 1542 | YYPOPSTACK (1); 1543 | yystate = *yyssp; 1544 | YY_STACK_PRINT (yyss, yyssp); 1545 | } 1546 | 1547 | YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN 1548 | *++yyvsp = yylval; 1549 | YY_IGNORE_MAYBE_UNINITIALIZED_END 1550 | 1551 | 1552 | /* Shift the error token. */ 1553 | YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); 1554 | 1555 | yystate = yyn; 1556 | goto yynewstate; 1557 | 1558 | 1559 | /*-------------------------------------. 1560 | | yyacceptlab -- YYACCEPT comes here. | 1561 | `-------------------------------------*/ 1562 | yyacceptlab: 1563 | yyresult = 0; 1564 | goto yyreturn; 1565 | 1566 | 1567 | /*-----------------------------------. 1568 | | yyabortlab -- YYABORT comes here. | 1569 | `-----------------------------------*/ 1570 | yyabortlab: 1571 | yyresult = 1; 1572 | goto yyreturn; 1573 | 1574 | 1575 | #if !defined yyoverflow || YYERROR_VERBOSE 1576 | /*-------------------------------------------------. 1577 | | yyexhaustedlab -- memory exhaustion comes here. | 1578 | `-------------------------------------------------*/ 1579 | yyexhaustedlab: 1580 | yyerror (YY_("memory exhausted")); 1581 | yyresult = 2; 1582 | /* Fall through. */ 1583 | #endif 1584 | 1585 | 1586 | /*-----------------------------------------------------. 1587 | | yyreturn -- parsing is finished, return the result. | 1588 | `-----------------------------------------------------*/ 1589 | yyreturn: 1590 | if (yychar != YYEMPTY) 1591 | { 1592 | /* Make sure we have latest lookahead translation. See comments at 1593 | user semantic actions for why this is necessary. */ 1594 | yytoken = YYTRANSLATE (yychar); 1595 | yydestruct ("Cleanup: discarding lookahead", 1596 | yytoken, &yylval); 1597 | } 1598 | /* Do not reclaim the symbols of the rule whose action triggered 1599 | this YYABORT or YYACCEPT. */ 1600 | YYPOPSTACK (yylen); 1601 | YY_STACK_PRINT (yyss, yyssp); 1602 | while (yyssp != yyss) 1603 | { 1604 | yydestruct ("Cleanup: popping", 1605 | yystos[+*yyssp], yyvsp); 1606 | YYPOPSTACK (1); 1607 | } 1608 | #ifndef yyoverflow 1609 | if (yyss != yyssa) 1610 | YYSTACK_FREE (yyss); 1611 | #endif 1612 | #if YYERROR_VERBOSE 1613 | if (yymsg != yymsgbuf) 1614 | YYSTACK_FREE (yymsg); 1615 | #endif 1616 | return yyresult; 1617 | } 1618 | #line 63 "parser.ypp" 1619 | 1620 | 1621 | --------------------------------------------------------------------------------