【发布时间】:2018-09-25 05:57:33
【问题描述】:
for(var x in z) {
a = x + 1 + 2;
foo();
}
function bar() {}
for(t in []){
function hello(a) {
a = t + 'hello' + 'world';
}
bar();
hello();
}
hello();
function hello() {}
15 * 30;
1 + 2 + 3;
a = 3 - 2 - 1;
a + 10;
假设我们有一个语义规则,即在调用函数时,该函数应在当前作用域或父作用域之前声明。
所以自从 foo();在上面的程序(第 3 行)中没有声明,我们需要打印一条错误消息。
对于第 13 行 hello() 没有声明,所以我们需要打印一条错误消息。
我们有 bison/flex 实现,但是缺少属性语法实现。
解析器:
%{
#include <stdio.h>
void yyerror(const char * msg){
printf("%s\n",msg);
}
%}
%token tFOR tIN tSEMICOLON tLPAR tLBRKT tLT tSTAR tPLUS tPERCENT tINT tREAL tSTRING tWHILE tVAR tCOMMA tRPAR tRBRKT tRBRACE tGT tEQ tMINUS tNOT tIDENT tIF tCOLON tLBRACE tELSE tEQCHECK tFUNCTION
%left tMINUS tPLUS
%left tSTAR
%left tPERCENT
%left tLT tGT tEQCHECK
%left tNOT
%%
prog: statementList
;
statementList: statementList statement
| statementList tSEMICOLON
|
;
statement: assign
| if
| expr
| while
| for
| functionCall
| functionDeclaration
;
assign: tIDENT tEQ expr
| tVAR tIDENT tEQ expr
;
if: ifPart elsePart
;
ifPart: tIF tLPAR expr tRPAR statementBlock
;
elsePart: tELSE statementBlock
|
;
while: tWHILE tLPAR expr tRPAR statementBlock
;
for: tFOR tLPAR tIDENT tIN expr tRPAR statementBlock
| tFOR tLPAR tVAR tIDENT tIN expr tRPAR statementBlock
;
functionDeclaration: tFUNCTION tIDENT tLPAR exprList tRPAR statementBlock
| tFUNCTION tIDENT tLPAR tRPAR statementBlock
;
statementBlock: tLBRACE statementList tRBRACE
;
functionCall: tIDENT tLPAR exprList tRPAR
| tIDENT tLPAR tRPAR
;
expr: tIDENT
| tREAL
| tINT
| tSTRING
| tLBRKT tRBRKT
| tLBRKT exprList tRBRKT
| tLBRACE tRBRACE
| tLBRACE propertyList tRBRACE
| tNOT expr
| expr tPLUS expr
| expr tMINUS expr
| expr tSTAR expr
| expr tEQCHECK expr
| expr tLT expr
| expr tGT expr
;
exprList: expr
| exprList tCOMMA expr
;
propertyList: tIDENT tCOLON expr
| propertyList tCOMMA tIDENT tCOLON expr
;
%%
int main() {
return yyparse();
}
扫描仪:
%{
#include "parser.tab.h"
%}
%%
in return tIN;
function return tFUNCTION;
for return tFOR;
while return tWHILE;
var return tVAR;
";" return tSEMICOLON;
"(" return tLPAR;
")" return tRPAR;
"[" return tLBRKT;
"]" return tRBRKT;
"<" return tLT;
">" return tGT;
"*" return tSTAR;
"+" return tPLUS;
"%" return tPERCENT;
"," return tCOMMA;
"{" return tRBRACE;
"}" return tLBRACE;
"==" return tEQCHECK;
"=" return tEQ;
"-" return tMINUS;
"!" return tNOT;
"-"?[0-9]+ return tINT;
("-"[0-9]+"."[0-9]+)|([0-9]*"."[0-9]+) return tREAL;
('[^']*')|(["][^"]*["]) return tSTRING;
[a-zA-Z_][a-zA-Z_0-9]* return tIDENT;
[ \t\n]
. return yytext[0];
%%
【问题讨论】:
-
不清楚这是一般问题还是特定于您对 bison/flex 的使用?如果是前者,这是一个非常广泛的问题。也许缩小到具体范围会有所帮助。
-
>> "我们有 bison/flex 实现,但是缺少属性语法实现。"是的。实施其中之一来进行语义检查。
标签: parsing compiler-construction bison semantics lex