gpt4 book ai didi

java - 调试 CUP 语法

转载 作者:行者123 更新时间:2023-12-02 02:09:07 28 4
gpt4 key购买 nike

我在调试 CUP 语法时陷入困境。

所以我在 CUP 中有以下语法:

/* Integer operators */
precedence left SUM_OP, SUBS_OP;
precedence left PROD_OP, DIV_OP;

/* Boolean operators */
precedence left EQ_OP, LT_OP, GT_OP, LET_OP, GET_OP;
precedence left OR_OP;
precedence left AND_OP;

start with statements;

statements ::= statement:s
| statement:s SEPARATOR
| SEPARATOR // Empty statement
| statement:s SEPARATOR statements:ss
;

statement ::= IF expression:e SEPARATOR statement:s
| IF expression:e statement:s
| IF expression:e SEPARATOR then_statement:then ELSE SEPARATOR statement:els
| IF expression:e then_statement:then ELSE SEPARATOR statement:els
| IF expression:e SEPARATOR then_statement:then ELSE statement:els
| IF expression:e then_statement:then ELSE statement:els
| WHILE expression:e SEPARATOR statement:s
| WHILE expression:e statement:s
| non_if_statement:s
;

then_statement ::= IF expression:e SEPARATOR then_statement:then ELSE SEPARATOR then_statement:els
| IF expression:e then_statement:then ELSE SEPARATOR then_statement:els
| IF expression:e SEPARATOR then_statement:then ELSE then_statement:els
| IF expression:e then_statement:then ELSE then_statement:els
| WHILE expression:e SEPARATOR then_statement:s
| WHILE expression:e then_statement:s
| non_if_statement:s
;

non_if_statement ::= START_BLOCK statements:s END_BLOCK
| declaration:d
| assignment:a
;

// The statement vs then_statement is for disambiguation purposes
// Solution taken from http://goldparser.org/doc/grammars/example-if-then-else.htm

/* Variable manipulation statements */
declaration ::= type:t IDENTIFIER:id
| type:t IDENTIFIER:id ASSIGN_OP expression:rhs
;

assignment ::= variable:lhs ASSIGN_OP expression:rhs
;

/* Variable manipulation auxiliar sintactic elements */
type ::= T_INT
| T_BOOL
| type:t T_ARRAY
;

variable ::= IDENTIFIER:id
| variable:id LBRACKET expression:idx RBRACKET
;

/* Integer or bool expressions */
expression ::= variable:v
| LPAREN expression:e RPAREN

// Int expressions
| INTEGER_LITERAL:c
| expression:op1 SUM_OP expression:op2
| expression:op1 SUBS_OP expression:op2
| expression:op1 PROD_OP expression:op2
| expression:op1 DIV_OP expression:op2

// Bool expressions
| BOOL_LITERAL:c
| expression:op1 OR_OP expression:op2
| expression:op1 AND_OP expression:op2
| NOT_OP expression:op1
| expression:op1 EQ_OP expression:op2
| expression:op1 LT_OP expression:op2
| expression:op1 GT_OP expression:op2
| expression:op1 LET_OP expression:op2
| expression:op1 GET_OP expression:op2
;

词法分析器将以下标记提供给 CUP 分析器:

 int id:i = intLiteral ;    
{
if id:i == intLiteral id:i = intLiteral ;
}


while id:i < intLiteral ;
{
id:i = id:i + intLiteral ;
}
if id:i <= intLiteral ;
{
bool id:a ;

bool id:b = boolLiteral ;
}
else ;
{
int id:j = intLiteral ;
}
if id:i >= intLiteral ;
{
id:i = id:i - intLiteral ;
{
id:i = intLiteral + intLiteral ;

}
}
else if id:i > intLiteral id:i = intLiteral ;

else id:i = intLiteral

(其中 ;SEPARATOR{ } 分隔 block 。

当我运行它时,我得到以下输出:

 int 
id:i
type ::= T_INT
=
intLiteral
;

expression ::= INTEGER_LITERAL
declaration ::= type IDENTIFIER ASSIGN_OP expression
non_if_statement ::= declaration
statement ::= non_if_statement
{
if
id:i
==
variable ::= IDENTIFIER
expression ::= variable
intLiteral
id:i
expression ::= INTEGER_LITERAL
expression ::= expression EQ_OP expression
=
variable ::= IDENTIFIER
intLiteral
;

expression ::= INTEGER_LITERAL
assignment ::= variable ASSIGN_OP expression
non_if_statement ::= assignment
statement ::= non_if_statement
statement ::= IF expression statement
}
statements ::= statement SEPARATOR
while
Error in line 7, column 1 : Syntax error
Error in line 7, column 1 : Couldn't repair and continue parse

(包含单个单词的行表示对导致打印标记的词法分析器的调用。包含 CUP 规则的行表示匹配该规则。第 7 行是带有 while 语句的行。)

看来这些 block 是失败的原因;当我从提供给语法的内容中删除所有 block 时,所有内容都会按我的预期进行解析。

但是,我不明白为什么这些 block 没有被正确解析。

对于可能出现的问题或如何进一步测试有什么想法吗?

编辑:如果您需要我可能省略回答的细节,完整的代码可以在 this repo 中找到。

最佳答案

你的语法使用分号的方式有点不正统。这会给你带来麻烦。

特别是,除了语句之间之外,分号似乎在任何地方都是可选的。所以这两个都可以

while i < 3; i = i + 1;   // ex. 1
while i < 3 i = i + 1; // ex. 2

但是你不能写

 i = 2 j = 3              // ex. 3

尽管这并不比 ex 更加含糊。上面 2 条。

无分号语法对于 block 来说看起来不那么奇怪:

while i < 3;  { i = i + 1;  } // ex. 4
while i < 3 { i = i + 1; } // ex. 5
{ i = 2 } { j = 3 } // ex. 6 Still illegal

为了进行解析,示例 6 需要用分号编写,在我看来,这是丑陋且不必要的:

{ i = 2 } ; { j = 3 }            // ex. 7

这就是你的解析器所提示的。尽管第 2-4 行的语句是用大括号括起来的,所以毫无疑问它的结束位置,但您的语法坚持使用分号。但下一个标记是 while,而不是分号,这是一个语法错误。

关于java - 调试 CUP 语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50297794/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com