Bison parser calculator - c++

this is my bison code:
%}
%union {
int int_val;
}
%left '+' '-'
%nonassoc '(' ')'
%token INTEGER PRINT
%type <int_val> expr_int INTEGER
%%
program: command '\n' { return 0; }
;
command: print_expr
;
print_expr: PRINT expr_int { cout<<$2<<endl; }
expr_int: expr_int '+' expr_int { $$ = $1 + $3; }
| expr_int '-' expr_int { $$ = $1 - $3; }
| '(' expr_int ')' { $$ = $2; }
| INTEGER
;
and this is the flex code:
%}
INTEGER [1-9][0-9]*|0
BINARY [-+]
WS [ \t]+
BRACKET [\(\)]
%%
print{WS} { return PRINT; }
{INTEGER} { yylval.int_val=atoi(yytext); return INTEGER; }
{BINARY}|\n { return *yytext; }
{BRACKET} { return *yytext; }
{WS} {}
. { return *yytext; }
%%
//////////////////////////////////////////////////
int yywrap(void) { return 1; } // Callback at end of file
Invalid inputs for the program are:
print 5
output:
5
input:
print (1+1)
output:
2
But for some reason, for the following inputs I do not get immediate error:
print (1+1))
output:
2
some error
input:
print 5!
output:
5
some error
I would like an error to be printed immediately, without commiting the print command and then throwing an error.
How should I change the program so it will not print errornous inputs?

Download the "flex & bison" book by John Levine or the "bison" manual from gnu. Both contain an infix calculator that you can reference.
The grammar you have written " '(' expr_int ')'" reduces to expr_int before the grammatically incorrect ')' in "(1 + 1))' is detected. That is the parser does:
(1 + 1)) => ( expr_int )) => expr_int)
and then sees the error. In order to capture the error you have to change the parser to see the error before the reduction, and you have to do it for all errors that you want treated. Therefore you would write (in this case):
expr_int '(' expr_int ')' ')' { this is an error message }
The short answer, after the long answer, is that it is impractical to generate a parser containing instances of all possible errors. What you have is fine for what you are doing. What you should explore is how to (gracefully) recover from an error rather than abandoning parsing.
Your "program" and "command" non-terminals can be combined as:
program: print-expr '\n' { return 0; }
On a separate note, your regular expressions can be rewritten to good effect as:
%%
INTEGER [0-9]+
WS [ \t]+
%%
print/{WS} { return PRINT; }
{INTEGER} { yylval.int_val=atoi(yytext); return INTEGER; }
'(' { return '('; }
')' { return ')'; }
'+' { return '+'; }
'-' { return '-'; }
{WS}* {}
\n { return '\n'; }
. { return *yytext; } // do you really want to do this?
%%

Create an end-of-line token (eg ;) for your language and make all lines statements exactly at the point when they encounter this end-of-line token.

Well that is because you are executing the code while parsing it. The good old bison calculator is meant to teach you how to write a grammar, not implement a full compiler/interpreter.
The normal way to build compiler/interpreter is the following:
lexer -> parser -> semantic analyser -> code generator -> interpreter
Granted building a fully fledged compiler may be overkill in your case. What you need to to is store the result somewhere and only output it after yyparse has returned without an error.

In yacc/bison, the code associated with a semantic action is executed as soon as the rule in question is reduced, which may happen immediately after the tokens for the rule have been shifted, before looking at any following context to see if there's and error or not (a so-called "default" reduction, used to make the parse tables smaller).
If you want to avoid printing an answer until an entire line is read (and recognized), you need to include the newline in the rule that has the action that prints the message. In your case, you can move the newline from the program rule to the print_expr rule:
program: command { return 0; } ;
print_expr: PRINT expr_int '\n' { cout<<$2<<endl; }
Of course, this will still give you an error (after printing output) if you give it multiple lines of input.

Related

bison error: rule given for Semi, which is a token?

my bison grammar met an error:
parser.yy:
%union {
Ast *ast;
char *str;
int tok;
}
%token <tok> NEWLINE SEMICOLON
%type <ast> Semi
%%
Semi: NEWLINE { $$ = new Ast($1); }
| SEMICOLON { $$ = new Ast($1); }
;
Statements: Statement
| Statement Semi Statements
;
Statement: ...
;
%%
It gives error message:
Parser.yy:xxx.x-x: error: rule given for Semi, which is a token
Is there a way to implement this ?
Or I have to write it like this: ?
Statements: Statement
| Statement NEWLINE Statements
| Statement SEMICOLON Statements
;
Semi is a token. It doesn't need define rule to return.
Just use it.

How to define unrecognized rules in Ocamlyacc

I'm working on company projet, where i have to create a compilator for a language using Ocamlyacc and Ocamllex. I want to know if is it possible to define a rule in my Ocamlyacc Parser that can tell me that no rules of my grammar matching the syntax of an input.
I have to insist that i'am a beginner in Ocamllex/Ocamlyacc
Thank you a lot for your help.
If no rule in your grammar matches the input, then Parsing.Parse_error exception is raised. Usually, this is what you want.
There is also a special token called error that allows you to resynchronize your parser state. You can use it in your rules, as it was a real token produced by a lexer, cf., eof token.
Also, I would suggest to use menhir instead of more venerable ocamlyacc. It is easier to use and debug, and it also comes with a good library of predefined grammars.
When you write a compiler for a language, the first step is to run your lexer and to check if your program is good from a lexical point of view.
See the below example :
{
open Parser (* The type token is defined in parser.mli *)
exception Eof
}
rule token = parse
[' ' '\t'] { token lexbuf } (* skip blanks *)
| ['\n' ] { EOL }
| ['0'-'9']+ as lxm { INT(int_of_string lxm) }
| '+' { PLUS }
| '-' { MINUS }
| '*' { TIMES }
| '/' { DIV }
| '(' { LPAREN }
| ')' { RPAREN }
| eof { raise Eof }
It's a lexer to recognize some arithmetic expressions.
If your lexer accepts the input then you give the sequence of lexemes to the parser which try to find if a AST can be build with the specified grammar. See :
%token <int> INT
%token PLUS MINUS TIMES DIV
%token LPAREN RPAREN
%token EOL
%left PLUS MINUS /* lowest precedence */
%left TIMES DIV /* medium precedence */
%nonassoc UMINUS /* highest precedence */
%start main /* the entry point */
%type <int> main
%%
main:
expr EOL { $1 }
;
expr:
INT { $1 }
| LPAREN expr RPAREN { $2 }
| expr PLUS expr { $1 + $3 }
| expr MINUS expr { $1 - $3 }
| expr TIMES expr { $1 * $3 }
| expr DIV expr { $1 / $3 }
| MINUS expr %prec UMINUS { - $2 }
;
This is a little program to parse arithmetic expression. A program can be rejected at this step because there is no rule of the grammar to apply in order to have an AST at the end. There is no way to define unrecognized rules but you need to write a grammar which define how a program can be accepted or rejected.
let _ =
try
let lexbuf = Lexing.from_channel stdin in
while true do
let result = Parser.main Lexer.token lexbuf in
print_int result; print_newline(); flush stdout
done
with Lexer.Eof ->
exit 0
If your compile the lexer, the parser and the last program, you have :
1 + 2 is accepted because there is no error lexical errors and an AST can be build corresponding to this expression.
1 ++ 2 is rejected : no lexical errors but there is no rule to build a such AST.
You can found more documentation here : http://caml.inria.fr/pub/docs/manual-ocaml-4.00/manual026.html

Yacc grammar producing incorrect terminal

I've been working on a hobby compiler for a while now, using lex and yacc for the parsing stage. This is all working fine for the majority of things, but when I added in if statements, the production rule for symbols is now giving the previous (or next?) item on the stack instead of the symbol value needed.
Grammar is given below with hopefully unrelated rules taken out:
%{
...
%}
%define parse.error verbose
%token ...
%%
Program:
Function { root->addChild($1);}
;
Function:
Type Identifier '|' ArgumentList '|' StatementList END
{ $$ = new FunctionDef($1, $2, $4, $6); }
/******************************************/
/* Statements and control flow ************/
/******************************************/
Statement:
Expression Delimiter
| VariableDeclaration Delimiter
| ControlFlowStatement Delimiter
| Delimiter
;
ControlFlowStatement:
IfStatement
;
IfStatement:
IF Expression StatementList END { $$ = new IfStatement($2, $3); }
| IF Expression StatementList ELSE StatementList END { $$ = new IfStatement($2, $3, $5);}
;
VariableDeclaration:
Type Identifier { $$ = new VariableDeclaration($1, $2);}
| Type Identifier EQUALS Expression { $$ = new VariableDeclaration($1, $2, $4);}
;
StatementList:
StatementList Statement { $1->addChild($2); }
| Statement { $$ = new GenericList($1); }
;
Delimiter:
';'
| NEWLINE
;
Type:
...
Expression:
...
PostfixExpression:
Value '[' Expression ']' { std::cout << "TODO: indexing operators ([ ])" << std::endl;}
| Value '.' SYMBOL { std::cout << "TODO: member access" << std::endl;}
| Value INCREMENT { $$ = new UnaryExpression(UNARY_POSTINC, $1); }
| Value DECREMENT { $$ = new UnaryExpression(UNARY_POSTDEC, $1); }
| Value '(' ')' { $$ = new FunctionCall($1, NULL); }
| Value '(' ExpressionList ')' { $$ = new FunctionCall($1, $3); }
| Value
;
Value:
BININT { $$ = new Integer(yytext, 2); }
| HEXINT { $$ = new Integer(yytext, 16); }
| DECINT { $$ = new Integer(yytext); }
| FLOAT { $$ = new Float(yytext); }
| SYMBOL { $$ = new Symbol(yytext); }
| STRING { $$ = new String(yytext); }
| LambdaFunction
| '(' Expression ')' { $$ = $2; }
| '[' ExpressionList ']' { $$ = $2;}
;
LambdaFunction:
...
%%
I cannot work out what about the control flow code can make the Symbol:
rule match something that isn't classed as a symbol from the lex definition:
symbol [a-zA-Z_]+(alpha|digit)*
...
{symbol} {return SYMBOL;}
Any help from somebody who knows about yacc and grammars in general would be very much appreciated. Also example files of the syntax it parses can be shown if necessary.
Thanks!
You cannot count on the value of yytext outside of a flex action.
Bison grammars typically read a lookahead token before deciding on how to proceed, so in a bison action, yytext has already been replaced with the token value of the lookahead token. (You can't count on that either, though: sometimes no lookahead token is needed.)
So you need to make a copy of yytext before the flex action returns and make that copy available to the bison grammar by placing it into the yylval semantic union.
See this bison FAQ entry
By the way, the following snippet from your flex file is incorrect:
symbol [a-zA-Z_]+(alpha|digit)*
In that regular expression, alpha and digit are just ordinary strings, so it is the same as [a-zA-Z_]+("alpha"|"digit")*, which means that it will match, for example, a_digitdigitdigit but not a_123. (It would have matched a_digitdigitdigit without the part following the +, so I presume that wasn't your intention.)
On the whole, I think it's better to use Posix character classes than either hand-written character classes or defined symbols, so I would write that as
symbol [[:alpha:]_]([[:alnum:]_]*[[:alnum:]])?
assuming that your intention is that a symbol can start but not end with an underscore, and end but not start with a digit. Using Posix character classes requires you to execute flex with the correct locale -- almost certainly the C locale -- but so do character ranges, so there is nothing to be lost by using the self-documenting Posix classes.
(Of course, I have no idea what your definitions of {alpha} and {digit} are, but it seems to me that they are either the same as [[:alpha:]] and [[:digit:]], in which case they are redundant, or different from the Posix classes, in which case they are confusing to the reader.)

OCaml interpreter: evaluate a function inside a function

I'm trying to write an interpreter in OCaml and I have a problem here.
In my program, I want to call a function like this, for example:
print (get_line 4) // print: print to stdout, get_line: get a specific line in a file
How can I do that? The problem is in our parser, I think so as it defines how a program will be run, how a function is defined and the flow of a program. This is what I have so far in parser an lexer (code below), but it didn't seem to work. I don't really see any difference between my code and the calculator on OCaml site, the statement inside the bracket is evaluated firstly, then return its value to its parent operation to do the next evaluating.
In my interpreter, the function get_line inside bracket is evaluate firstly, but I don't think it returns the value to print function, or it does but wrong type (checked, but I don't think it's this error).
One difference between calculator and my interpreter is that the calculator is working with primitive types, mine are functions. But they should be similar.
This is my code, just a part of it:
parser.mly:
%token ODD
%token CUT
%start main
%type <Path.term list> main
%%
main:
| expr EOL main {$1 :: $3}
| expr EOF { [$1] }
| EOL main { $2 }
;
expr:
| ODD INT { Odd $2}
| ODD LPAREN INT RPAREN expr { Odd $3 }
| CUT INT INT { Cut ($2, $3)}
| CUT INT INT expr { Cut ($2, $3) }
lexer.mll:
{
open Parser
}
(* define all keyword used in the program *)
rule main =
parse
| ['\n'] { EOL }
| ['\r']['\n'] { EOL }
| [' ''\t''\n'] { main lexbuf }
| '(' { LPAREN }
| ')' { RPAREN }
| "cut" { CUT }
| "trunclength" { TRUNCLENGTH }
| "firstArithmetic" { FIRSTARITH }
| "f_ArithmeticLength" { F_ARITHLENGTH }
| "secondArithmetic" { SECARITH }
| "s_ArithmeticLength" { S_ARITHLENGTH }
| "odd" { ODD }
| "oddLength" { ODDLENGTH }
| "zip" { ZIP }
| "zipLength" { ZIPLENGTH }
| "newline" { NEWLINE }
| eof { EOF }
| ['0' - '9']+ as lxm { INT(int_of_string lxm) }
| ['a'-'z''A'-'Z'] ['a'-'z''A'-'Z''0'-'9']* as lxm { STRING lxm }
| ODD LPAREN INT RPAREN expr { Odd $3 }
Your grammar rule requires an INT between parenthesis. You need to change that to an expr. There are a number of other issues with this, but I'll leave it at that.
First, you parser only tries to build a list of Path.term, but what do you want to do with it?
Then, there are many things wrong with your parser, so I don't really know where to start. For instance, the second and fourth case of the expr rule totally ignore the last expr. Moreover, your parser only recognize expressions containing "odd <int>" (or "odd (<int>)") and "cut <int> <int>", so how is it supposed to evaluate print and get_line? You should edit your question and try to make it clearer.
To evaluate expressions, you can
do it directly inside the semantic-actions (as in the calculator example),
or (better) build an AST (for Abstract Syntax Tree) with your parser and then interpret it.
If you want to interpret print (get_line 4), your parser need to know what print and get_line mean. In your code, your parser will see print or get_line as a STRING token (having a string value). As they seem to be keywords in your language, your lexer should recognize them and return a specific token.

Bison outputting string after the wrong line

The input
1 -- Narrowing Variable Initialization
2
3 function main a: integer returns integer;
4 b: integer is a * 2.;
5 begin
6 if a <= 0 then
7 b + 3;
8 else
9 b * 4;
10 endif;
11 end;
is yielding the output
1 -- Narrowing Variable Initialization
2
3 function main a: integer returns integer;
4 b: integer is a * 2.;
5 begin
Narrowing Variable Initialization
6 if a <= 0 then
7 b + 3;
8 else
9 b * 4;
10 endif;
11 end;
Instead of placing that error message under line 4, which is where the error actually occurs. I've looked at it for hours and can't figure it out.
%union
{
char* ident;
Types types;
}
%token <ident> IDENTIFIER
%token <types> INTEGER_LITERAL
%token <types> REAL_LITERAL
%token BEGIN_
%token FUNCTION
%token IS
%token <types> INTEGER
%token <types> REAL
%token RETURNS
%type <types> expression
%type <types> factor
%type <types> literal
%type <types> term
%type <types> statement
%type <types> type
%type <types> variable
%%
program:
/* empty */ |
functions ;
functions:
function_header_recovery body ; |
function_header_recovery body functions ;
function_header_recovery:
function_header ';' |
error ';' ;
function_header:
FUNCTION {locals = new Locals();} IDENTIFIER optional_parameters RETURNS type {globals->insert($3,locals->tList);} ;
optional_parameters:
/* empty */ |
parameters;
parameters:
IDENTIFIER ':' type {locals->insert($1, $3); locals->tList.push_back($3); } |
IDENTIFIER ':' type {locals->insert($1, $3); locals->tList.push_back($3); } "," parameters;
type:
INTEGER | REAL ;
body:
optional_variables BEGIN_ statement END ';' ;
optional_variables:
/* empty */ |
variables ;
variables:
variable IS statement {checkTypes($1, $3, 2);} |
variable IS statement {checkTypes($1, $3, 2);} variables ;
variable:
IDENTIFIER ':' type {locals->insert($1, $3);} {$$ = $3;} ;
statement:
expression ';' |
...
Types checkTypes(Types left, Types right, int flag)
{
if (left == right)
{
return left;
}
if (flag == 1)
{
Listing::appendError("Conditional Expression Type Mismatch", Listing::SEMANTIC);
}
else if (flag == 2)
{
if (left < right)
{
Listing::appendError("Narrowing Variable Initialization", Listing::SEMANTIC);
}
}
return REAL_TYPE;
}
printing being handled by:
void Listing::nextLine()
{
printf("\n");
if (error == "")
{
lineNo++;
printf("%4d%s",lineNo," ");
}
else
{
printf("%s", error.c_str());
error = "";
nextLine();
}
}
void Listing::appendError(const char* errText, int errEnum)
{
error = error + errText;
if (errEnum == 997)
{
lexErrCount++;
}
else if (errEnum == 998)
{
synErrCount++;
}
else if (errEnum == 999)
{
semErrCount++;
}
}
void Listing::display()
{
printf( "\b\b\b\b\b\b " );
if (lexErrCount + synErrCount + semErrCount > 0)
{
printf("\n\n%s%d","Lexical Errors ",lexErrCount);
printf("\n%s%d","Syntax Errors ",synErrCount);
printf("\n%s%d\n","Semantic Errors ",semErrCount);
}
else
{
printf("\nCompiled Successfully\n");
}
}
That's just the way bison works. It produces a one-token lookahead parser, so your production actions don't get triggered until it has read the token following the production. Consequently, begin must be read before the action associated with variables happens. (bison never tries to combine actions, even if they are textually identical. So it really cannot know which variables production applies and which action to execute until it sees the following token.)
There are various ways to associate a line number and/or column position with each token, and to use that information when an error message is to be produced. Interspersing the errors and/or warnings with the input text, in general, requires buffering the input; for syntax errors, you only need to buffer until the next token but that is not a general solution; in some cases, for example, you may want to associate an error with an operator, for example, but the error won't be detected until the operator's trailing argument has been parsed.
A simple technique to correctly intersperse errors/warnings with source is to write all the errors/warnings to a temporary file, putting the file offset at the front of each error. This file can then be sorted, and the input can then be reread, inserting the error messages at appropriate points. The nice thing about this strategy is that it avoids having to maintain line numbers for each error, which noticeably slows down lexical analysis. Of course, it won't work so easily if you allow constructs like C's #include.
Because generating good error messages is hard, and even tracking locations can slow parsing down quite a bit, I've sometimes used the strategy of parsing input twice if an error is detected. The first parse only detects errors and fails early if it can't do anything more reasonable; if an error is detected, the input is reparsed with a more elaborate parser which carefully tracks file locations and possibly even uses heuristics like indentation depth to try to produce better error messages.
As rici notes, bison produces an LALR(1) parser, so it uses one token of lookahead to know what action to take. However, it doesn't ALWAYS use a token of lookahead -- in some cases (where there's only one possibility regardless of lookahead), it uses default reductions which can reduce a rule (and run the associated action) WITHOUT lookahead.
In your case, you can take advantage of that to get the action to run without lookahead if you really need to. The particular rule in question (which triggers the requirement for lookahead) is:
variables:
variable IS statement {checkTypes($1, $3, 2);} |
variable IS statement {checkTypes($1, $3, 2);} variables ;
in this case, after seeing a variable IS statement, it needs to see the next token to decide if there are more variable declarations in order to know which action (the first or the second) to run. But as the two actions are really the same, you could combine them into a single action:
variables: vardecl | vardecl variables ;
vardecl: variable IS statement {checkTypes($1, $3, 2);}
which would end up using a default reduction as it doesn't need the lookahead to decide between two reductions/actions.
Note that the above depends on being able to find the end of a statement without lookahead, which should be the case as long as all statements end unambiguously with a ;