%{
#include <cstdio>
#include <string>
#define YYDEBUG 1 <-- set debug on
%}
%start input
%token DIGIT
%left '+' '-'
%left '*' '/'
%name-prefix="Scalc" <-- classname prefix (ScalcPushParser)
%%
input: /* empty */ |
| input line |
; |
|
line: '\n' |
| exp '\n' { printf ("\t%d\n", $1); } |
; |
| pull grammar == push grammar
exp: DIGIT { $$ = $1; } |
| exp '+' exp { $$ = $1 + $3; } |
| exp '-' exp { $$ = $1 - $3; } |
| exp '*' exp { $$ = $1 * $3; } |
| exp '/' exp { $$ = $1 / $3; } |
| '-' exp { $$ = -$2; } |
; |
%%
class MyScalcPushParser:public ScalcPushParser <-- implement debugPrint(...) and yyerror(...)
{
private:
virtual void debugPrint(int aInt) const
{
printf("%d",aInt);
}
virtual void debugPrint(std::string s) const
{
printf("%s",s.c_str());
}
public:
MyScalcPushParser() {}
virtual void yyerror(const char* s) const
{
printf("%s\n",s);
}
};
void lex(MyScalcPushParser *parser)
{
MyScalcPushParser::SemanticType token;
while((token=fgetc(stdin))!=EOF) {
if(isblank(token)) {
continue;
}
if(isdigit(token)) {
ungetc(token,stdin);
scanf("%d",&token);
parser->parseToken(DIGIT,token); <-- instead of return(...) parseToken(...)
} else {
parser->parseToken(token,token);
}
}
parser->parseToken(0,token); <-- parse EOF
return;
}
int main()
{
MyScalcPushParser *parser=new MyScalcPushParser();
parser->setDebug(1);
lex(parser);
delete parser;
return 0;
}