Parsing 优化Bison语法
我有一个类似C语言的语法,我想为它做一个解析器,但是当我把语法放进去时,它告诉我移位/减少冲突。我试图修改一些语法,但似乎找不到其他方法来改进语法。任何帮助都将不胜感激:D以下是语法:Parsing 优化Bison语法,parsing,grammar,bison,flex-lexer,Parsing,Grammar,Bison,Flex Lexer,我有一个类似C语言的语法,我想为它做一个解析器,但是当我把语法放进去时,它告诉我移位/减少冲突。我试图修改一些语法,但似乎找不到其他方法来改进语法。任何帮助都将不胜感激:D以下是语法: Program: Decl | Program Decl ; Decl: VariableDecl | FunctionDecl | ClassDecl | InterfaceDecl ; VariableDecl: Variable SEMICOL
Program: Decl
| Program Decl
;
Decl: VariableDecl
| FunctionDecl
| ClassDecl
| InterfaceDecl
;
VariableDecl: Variable SEMICOLON
;
Variable: Type IDENTIFIER
;
Type: TOKINT
| TOKDOUBLE
| TOKBOOL
| TOKSTRING
| IDENTIFIER
| Type BRACKETS
;
FunctionDecl: Type IDENTIFIER OPARENS Formals CPARENS StmtBlock
| TOKVOID IDENTIFIER OPARENS Formals CPARENS StmtBlock
;
Formals: VariablePlus
| /* epsilon */
;
VariablePlus: Variable
| VariablePlus COMMA Variable
;
ClassDecl: TOKCLASS IDENTIFIER OptExtends OptImplements OBRACE ListaField CBRACE
;
OptExtends: TOKEXTENDS IDENTIFIER
| /* epsilon */
;
OptImplements: TOKIMPLEMENTS ListaIdent
| /* epsilon */
;
ListaIdent: ListaIdent COMMA IDENTIFIER
| IDENTIFIER
;
ListaField: ListaField Field
| /* epsilon */
;
Field: VariableDecl
| FunctionDecl
;
InterfaceDecl: TOKINTERFACE IDENTIFIER OBRACE ListaProto CBRACE
;
ListaProto: ListaProto Prototype
| /* epsilon */
;
Prototype: Type IDENTIFIER OPARENS Formals CPARENS SEMICOLON
| TOKVOID IDENTIFIER OPARENS Formals CPARENS SEMICOLON
;
StmtBlock: OBRACE ListaOptG CBRACE
;
ListaOptG: /* epsilon */
| VariableDecl ListaOptG
| Stmt ListaOptG
;
Stmt: OptExpr SEMICOLON
| IfStmt
| WhileStmt
| ForStmt
| BreakStmt
| ReturnStmt
| PrintStmt
| StmtBlock
;
OptExpr: Expr
| /* epsilon */
;
IfStmt: TOKIF OPARENS Expr CPARENS Stmt OptElse
;
OptElse: TOKELSE Stmt
| /* epsilon */
;
WhileStmt: TOKWHILE OPARENS Expr CPARENS Stmt
;
ForStmt: TOKFOR OPARENS OptExpr SEMICOLON Expr SEMICOLON OptExpr CPARENS Stmt
;
ReturnStmt: TOKRETURN OptExpr SEMICOLON
;
BreakStmt: TOKBREAK SEMICOLON
;
PrintStmt: TOKPRINT OPARENS ListaExprPlus CPARENS SEMICOLON
;
ListaExprPlus: Expr
| ListaExprPlus COMMA Expr
;
Expr: LValue LOCATION Expr
| Constant
| LValue
| TOKTHIS
| Call
| OPARENS Expr CPARENS
| Expr PLUS Expr
| Expr MINUS Expr
| Expr TIMES Expr
| Expr DIVIDED Expr
| Expr MODULO Expr
| MINUS Expr
| Expr LESSTHAN Expr
| Expr LESSEQUALTHAN Expr
| Expr GREATERTHAN Expr
| Expr GREATEREQUALTHAN Expr
| Expr EQUALS Expr
| Expr NOTEQUALS Expr
| Expr AND Expr
| Expr OR Expr
| NOT Expr
| TOKNEW OPARENS IDENTIFIER CPARENS
| TOKNEWARRAY OPARENS Expr COMMA Type CPARENS
| TOKREADINTEGER OPARENS CPARENS
| TOKREADLINE OPARENS CPARENS
| TOKMALLOC OPARENS Expr CPARENS
;
LValue: IDENTIFIER
| Expr PERIOD IDENTIFIER
| Expr OBRACKET Expr CBRACKET
;
Call: IDENTIFIER OPARENS Actuals CPARENS
| Expr PERIOD IDENTIFIER OPARENS Actuals CPARENS
| Expr PERIOD LibCall OPARENS Actuals CPARENS
;
LibCall: TOKGETBYTE OPARENS Expr CPARENS
| TOKSETBYTE OPARENS Expr COMMA Expr CPARENS
;
Actuals: ListaExprPlus
| /* epsilon */
;
Constant: INTCONSTANT
| DOUBLECONSTANT
| BOOLCONSTANT
| STRINGCONSTANT
| TOKNULL
;
冲突shift/reduce或reduce/reduce意味着你的语法不是LALR1,因此在没有帮助的情况下bison无法直接处理。有一些显而易见的问题: 表达式歧义-语法中没有优先级,所以像a+b*c这样的东西是歧义的。您可以通过添加优先级规则或将Expr规则拆分为单独的AdditiveExpr、乘法eExpr、ConditionalExpr等规则来解决此问题 悬空-如果a如果b x;否则y;-else可以与任一if匹配。如果默认的移位是正确的,则可以忽略此项(通常针对这种特定情况),但忽略错误总是危险的,或者拆分Stmt规则
有很多关于语法和语法分析的书都会对此有所帮助。冲突shift/reduce或reduce/reduce意味着你的语法不是LALR1,因此没有帮助bison无法直接处理。有一些显而易见的问题: 表达式歧义-语法中没有优先级,所以像a+b*c这样的东西是歧义的。您可以通过添加优先级规则或将Expr规则拆分为单独的AdditiveExpr、乘法eExpr、ConditionalExpr等规则来解决此问题 悬空-如果a如果b x;否则y;-else可以与任一if匹配。如果默认的移位是正确的,则可以忽略此项(通常针对这种特定情况),但忽略错误总是危险的,或者拆分Stmt规则
有很多关于语法和语法分析的书可以帮助解决这个问题。我学校服务器上的老版Bison说,你有241个移位/减少冲突。一个是悬而未决的if/else语句。使用OptElse并不能解决这个问题。您只需写出IfStmt和IfElseStmt,然后在bison中使用%nonassoc和%prec选项来修复它 你的表情几乎是其他240场冲突的焦点。您需要做的是,要么强制优先规则混乱不堪,要么将算术表达式分解为以下内容:
AddSubtractExpr: AddSubtractExpr PLUS MultDivExpr | ....
;
MultDivExpr: MultiDivExpr TIMES Factor | ....
;
Factor: Variable | LPAREN Expr RPAREN | call | ...
;
由于Bison生成了一个自底向上的解析器,类似这样的东西将为您提供正确的操作顺序。如果你有《龙之书》第一版的副本,你应该看看附录a中的语法。我相信第二版对简单的表达也有类似的规则。我学校服务器上的老版Bison说你有241个移位/减少冲突。一个是悬而未决的if/else语句。使用OptElse并不能解决这个问题。您只需写出IfStmt和IfElseStmt,然后在bison中使用%nonassoc和%prec选项来修复它 你的表情几乎是其他240场冲突的焦点。您需要做的是,要么强制优先规则混乱不堪,要么将算术表达式分解为以下内容:
AddSubtractExpr: AddSubtractExpr PLUS MultDivExpr | ....
;
MultDivExpr: MultiDivExpr TIMES Factor | ....
;
Factor: Variable | LPAREN Expr RPAREN | call | ...
;
由于Bison生成了一个自底向上的解析器,类似这样的东西将为您提供正确的操作顺序。如果您有《龙之书》第一版的副本,您应该看看附录a中的语法。我相信第二版对简单表达式也有类似的规则。您能提供错误信息吗?除了移位减少错误,您正在使用正确的递归规则,例如Expr:Expr+Expr,这些规则效率很低。有关详细信息,请参阅Bison手册,您可以提供错误消息吗?除了shift-reduce错误之外,您还使用了正确的递归规则,例如Expr:Expr+Expr,这些规则效率非常低。详见《野牛手册》,