我有一个简单的语法,我已经构建了一个问题我不知道如何解决:
start syntax Prog = prog: Type Id;
syntax Dot = {Id "."}+ ;
syntax Id =
id: [A-Z_a-z] !>> [0-9A-Z_a-z] \ KW
| Rv
;
syntax Rv = rv: "$" [a-z_A-Z][a-z_A-Z0-9]* ;
syntax Type =
Rv
| Ref
;
syntax Ref =
Dot
| s: "str"
;
keyword KW = "str" ;
layout LAYOUTLIST = LAYOUT* !>> [\t-\n\r\ /] ;
lexical LAYOUT = [\t-\n\r\ ] ;
问题在于我们可以通过三种不同的方式(rv
- > Id
)和(Rv
- > {{1}来解析Type
})和(Rv
- > Type
- > Ref
- > Dot
- > Id
)。问题是我需要Rv
和Type
s Id
s。所以,给出一个简单的程序:
Rv
我的想法是我可以通过将$a x
的规则更改为:
Type
希望解析器在检查是否可以在syntax Type =
Rv
> Ref
;
分支中解析之前将Rv
与Type
相关联。我运行了一些歧义诊断,但我不确定该怎么做:
Ref
所以,我需要的是 info(
"Ambiguity cluster with 2 alternatives",
|cwd:///grammar.txt|(0,3,<1,0>,<1,3>)),
info(
"Production unique to the one alternative: Type = Rv ;",
|cwd:///grammar.txt|(0,3,<1,0>,<1,3>)),
info(
"Production unique to the other alternative: Dot = {Id \".\"}+ ;",
|cwd:///grammar.txt|(0,3,<1,0>,<1,3>)),
info(
"Production unique to the other alternative: {Id \".\"}+;",
|cwd:///grammar.txt|(0,3,<1,0>,<1,3>)),
info(
"Production unique to the other alternative: Ref = Dot ;",
|cwd:///grammar.txt|(0,3,<1,0>,<1,3>)),
info(
"Production unique to the other alternative: Type = Ref ;",
|cwd:///grammar.txt|(0,3,<1,0>,<1,3>)),
info(
"Production unique to the other alternative: Id = Rv ;",
|cwd:///grammar.txt|(0,3,<1,0>,<1,3>)),
info(
"The alternatives have different productions at the top, one has \n Type = Rv \nwhile the other has\n Type = Ref ",
|cwd:///grammar.txt|(0,3,<1,0>,<1,3>)),
warning(
"You should give this production a good label: \n Ref = Dot ]",
|cwd:///grammar.txt|(0,3,<1,0>,<1,3>)),
error(
"To fix this issue, you could restrict the nesting of\n Ref = Dot \nunder\n Type = Ref \nusing the ! operator on argument 0: !labelX\nHowever, you should realize that you are introducing a restriction that makes the language smaller",
|cwd:///grammar.txt|(0,3,<1,0>,<1,3>))
s在解析时没有歧义的Rv
和Type
的某种方式。这可能吗?
谢谢!
答案 0 :(得分:0)
在这种情况下,如果您控制语言的语法,则可以通过添加显式运算符或某种形式的唯一括号或分隔符语法来选择非模糊语言。换句话说,我不认为语法对于非本质上不明确的语言而言是偶然的模糊,并且应该存在非模糊的语法。我认为目前设想的语言没有非模糊的无上下文语法。
示例修复:
syntax Type
= Rv
| "&" Ref
;
另一种方法是尝试使用Rascal的消歧机制来破解你的方式,但它们不会通过设计提供任何有序的回溯行为。它将使语法的语义依赖于解析算法(它控制语法规则的执行顺序)。
您可以尝试使用!>>
和\
运算符以及!
来排除某些句子和派生词,但如果可以在不丢失语言句子的情况下完成此操作,则诊断工具会给了你这个建议。所以这些黑客可能会解决这种模糊性,但它们也会改变语言的设计,使程序员更难以预测允许的内容和不允许的内容。
优先级机制也没有帮助,因为它只是为相互递归规则设计的,具有不同的优先级,例如1 + (2 * 3)
vs (1 + 2) * 3
简而言之:我会选择对语言进行一两次更改,以使语法对于一般解析器和人眼都变得明确。