Start working on parse

This commit is contained in:
Danila Fedorin 2019-05-11 22:34:26 -07:00
parent b7ed17742e
commit 8d8f3f8c10
3 changed files with 76 additions and 47 deletions

View File

@ -1,13 +1,13 @@
all: scan all: scan
scan: main.cpp scanner.cpp scan: main.cpp scanner.cpp parser.cpp
g++ main.cpp scanner.cpp -o scan g++ main.cpp scanner.cpp parser.cpp -o scan
scanner.cpp: scanner.l scanner.cpp: scanner.l
flex -o scanner.cpp scanner.l flex -o scanner.cpp scanner.l
parser.tab.cpp: parser.y parser.cpp parser.hpp: parser.y
bison -d parser.y bison -d -o parser.cpp parser.y
clean: clean:
rm -f scan scanner.cpp rm -f scan scanner.cpp

View File

@ -1,6 +1,8 @@
%{ %{
#include <string> #include <string>
#include <iostream>
#include "parser.hpp"
%} %}
@ -19,6 +21,8 @@
%token RETURN %token RETURN
%token WHILE %token WHILE
%token BOOLEAN %token BOOLEAN
%token FLOAT
%token INTEGER
%token IDENTIFIER %token IDENTIFIER
%token ASSIGN %token ASSIGN
%token PLUS %token PLUS
@ -36,23 +40,36 @@
%token COMMA %token COMMA
%token COLON %token COLON
%define api.value.type { std::string } %define api.value.type { const char* }
%define api.pure full %define api.pure full
%define api.push-pull push %define api.push-pull push
%start program
%{
void yyerror(const char* s) {
std::cout << s << std::endl;
}
%}
%% %%
program program
: statements {} : program stmt
| stmt
; ;
statements stmt
: statement statements {} : expr NEWLINE;
| statement {}
expr
: assign
| INTEGER
; ;
statement assign
: PLUS {} : IDENTIFIER ASSIGN expr
; ;
%% %%

View File

@ -14,6 +14,7 @@
#include <iostream> #include <iostream>
#include <stack> #include <stack>
#include <cstdlib> #include <cstdlib>
#include "parser.hpp"
/* /*
* We'll use this stack to keep track of indentation level, as described in * We'll use this stack to keep track of indentation level, as described in
@ -22,6 +23,17 @@
* https://docs.python.org/3/reference/lexical_analysis.html#indentation * https://docs.python.org/3/reference/lexical_analysis.html#indentation
*/ */
std::stack<int> _indent_stack; std::stack<int> _indent_stack;
yypstate* state = yypstate_new();
#define PUSH_TOKEN(i, str) do { \
std::cout << i << ", " << str << std::endl; \
YYSTYPE temp = str; \
int s = yypush_parse(state, i, &temp); \
if (s != YYPUSH_MORE) { \
yypstate_delete(state); \
return s; \
} } while(0);
%} %}
%% %%
@ -59,7 +71,7 @@ std::stack<int> _indent_stack;
* then emit an INDENT and push the new indentation level onto * then emit an INDENT and push the new indentation level onto
* the stack. * the stack.
*/ */
std::cout << "INDENT" << std::endl; PUSH_TOKEN(INDENT, "");
_indent_stack.push(yyleng); _indent_stack.push(yyleng);
} else { } else {
/* /*
@ -70,7 +82,7 @@ std::stack<int> _indent_stack;
*/ */
while (!_indent_stack.empty() && _indent_stack.top() != yyleng) { while (!_indent_stack.empty() && _indent_stack.top() != yyleng) {
_indent_stack.pop(); _indent_stack.pop();
std::cout << "DEDENT" << std::endl; PUSH_TOKEN(DEDENT, "");
} }
/* /*
@ -95,13 +107,13 @@ std::stack<int> _indent_stack;
*/ */
while (_indent_stack.top() != 0) { while (_indent_stack.top() != 0) {
_indent_stack.pop(); _indent_stack.pop();
std::cout << "DEDENT" << std::endl; PUSH_TOKEN(DEDENT, "");
} }
REJECT; REJECT;
} }
\r?\n { \r?\n {
std::cout << "NEWLINE" << std::endl; PUSH_TOKEN(NEWLINE, "");
} }
<<EOF>> { <<EOF>> {
@ -111,58 +123,58 @@ std::stack<int> _indent_stack;
*/ */
while(_indent_stack.top() != 0) { while(_indent_stack.top() != 0) {
_indent_stack.pop(); _indent_stack.pop();
std::cout << "DEDENT" << std::endl; PUSH_TOKEN(DEDENT, "");
} }
yyterminate(); yyterminate();
} }
[ \t] { /* Ignore spaces that haven't been handled above. */ } [ \t] { /* Ignore spaces that haven't been handled above. */ }
"and" { std::cout << "AND\t\t" << yytext << std::endl; } "and" { PUSH_TOKEN(AND, ""); }
"break" { std::cout << "BREAK\t\t" << yytext << std::endl; } "break" { PUSH_TOKEN(BREAK, ""); }
"def" { std::cout << "DEF\t\t" << yytext << std::endl; } "def" { PUSH_TOKEN(DEF, ""); }
"elif" { std::cout << "ELIF\t\t" << yytext << std::endl; } "elif" { PUSH_TOKEN(ELIF, ""); }
"else" { std::cout << "ELSE\t\t" << yytext << std::endl; } "else" { PUSH_TOKEN(ELSE, ""); }
"for" { std::cout << "FOR\t\t" << yytext << std::endl; } "for" { PUSH_TOKEN(FOR, ""); }
"if" { std::cout << "IF\t\t" << yytext << std::endl; } "if" { PUSH_TOKEN(IF, ""); }
"not" { std::cout << "NOT\t\t" << yytext << std::endl; } "not" { PUSH_TOKEN(NOT, ""); }
"or" { std::cout << "OR\t\t" << yytext << std::endl; } "or" { PUSH_TOKEN(OR, ""); }
"return" { std::cout << "RETURN\t\t" << yytext << std::endl; } "return" { PUSH_TOKEN(RETURN, ""); }
"while" { std::cout << "WHILE\t\t" << yytext << std::endl; } "while" { PUSH_TOKEN(WHILE, ""); }
"True" { std::cout << "BOOLEAN\t\t" << true << std::endl; } "True" { PUSH_TOKEN(BOOLEAN, "True"); }
"False" { std::cout << "BOOLEAN\t\t" << false << std::endl; } "False" { PUSH_TOKEN(BOOLEAN, "True"); }
[a-zA-Z_][a-zA-Z0-9_]* { [a-zA-Z_][a-zA-Z0-9_]* {
std::cout << "IDENTIFIER\t" << yytext << std::endl; PUSH_TOKEN(IDENTIFIER, "");
} }
-?[0-9]*"."[0-9]+ { -?[0-9]*"."[0-9]+ {
std::cout << "FLOAT\t\t" << atof(yytext) << std::endl; PUSH_TOKEN(FLOAT, "");
} }
-?[0-9]+ { -?[0-9]+ {
std::cout << "INTEGER\t\t" << atoi(yytext) << std::endl; PUSH_TOKEN(INTEGER, "");
} }
"=" { std::cout << "ASSIGN\t\t" << yytext << std::endl; } "=" { PUSH_TOKEN(ASSIGN, ""); }
"+" { std::cout << "PLUS\t\t" << yytext << std::endl; } "+" { PUSH_TOKEN(PLUS, ""); }
"-" { std::cout << "MINUS\t\t" << yytext << std::endl; } "-" { PUSH_TOKEN(MINUS, ""); }
"*" { std::cout << "TIMES\t\t" << yytext << std::endl; } "*" { PUSH_TOKEN(TIMES, ""); }
"/" { std::cout << "DIVIDEDBY\t" << yytext << std::endl; } "/" { PUSH_TOKEN(DIVIDEDBY, ""); }
"==" { std::cout << "EQ\t\t" << yytext << std::endl; } "==" { PUSH_TOKEN(EQ, ""); }
"!=" { std::cout << "NEQ\t\t" << yytext << std::endl; } "!=" { PUSH_TOKEN(NEQ, ""); }
">" { std::cout << "GT\t\t" << yytext << std::endl; } ">" { PUSH_TOKEN(GT, ""); }
">=" { std::cout << "GTE\t\t" << yytext << std::endl; } ">=" { PUSH_TOKEN(GTE, ""); }
"<" { std::cout << "LT\t\t" << yytext << std::endl; } "<" { PUSH_TOKEN(LT, ""); }
"<=" { std::cout << "LTE\t\t" << yytext << std::endl; } "<=" { PUSH_TOKEN(LTE, ""); }
"(" { std::cout << "LPAREN\t\t" << yytext << std::endl; } "(" { PUSH_TOKEN(LPAREN, ""); }
")" { std::cout << "RPAREN\t\t" << yytext << std::endl; } ")" { PUSH_TOKEN(RPAREN, ""); }
"," { std::cout << "COMMA\t\t" << yytext << std::endl; } "," { PUSH_TOKEN(COMMA, ""); }
":" { std::cout << "COLON\t\t" << yytext << std::endl; } ":" { PUSH_TOKEN(COLON, ""); }
. { . {
std::cerr << "Unrecognized token on line " << yylineno << ": " std::cerr << "Unrecognized token on line " << yylineno << ": "