Start working on parse
This commit is contained in:
parent
b7ed17742e
commit
8d8f3f8c10
8
Makefile
8
Makefile
|
@ -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
|
||||||
|
|
31
parser.y
31
parser.y
|
@ -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
|
||||||
;
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
84
scanner.l
84
scanner.l
|
@ -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 << ": "
|
||||||
|
|
Loading…
Reference in New Issue
Block a user