鉴于语法规则(BNF,|
表示或):
x := a | x x | x + x | x + "x" | "x" + x | "x" + "x"
,
+
左关联(a+a+a
表示(a+a)+a
),aaa
表示(aa)a
,而不是a(aa)
),+
懒洋洋地吃操作数(aa+aa
表示a(a+a)a
)。 问题: 这个语法是不明确的? I.e.是否有可能以两种不同的方式解析字符串?
示例:
允许:a
,a+a
,a+"a"
,"a+a"+"a+a"
(读作(a+a)+(a+a)
),""a"+"a""+"a"
(读作((a)+(a))+(a)
}),a+a+a
,a+"a"+a
。
禁止使用:"a+a"
,+"a"
,a++a
,"a"
,a+"a
,""a+a"+a"
。
应用程序: 我讨厌在LaTeX中转义{
和}
,所以我想制作一个只有一个字符的LaTeX方言需要进行转义,例如将{
和}
替换为一个字符"
,然后编写类似""1+2"/3"^"a+b"
而不是{\frac{1+2}{3}}^{a+b}
的内容。
答案 0 :(得分:2)
Here是一个快速而又脏的脚本,使用Marpa::R2,一个Perl Marpa, a general BNF parser接口来解析输入,并使用您提供的语法及其修改版本,支持懒惰吃和左关联,但不禁止"a"
:
code,output。
对于您提供的输入,语法并不含糊,因为parse()会抛出异常。
希望这有帮助。
P.S。使用Marpa的一般BNF解析功能为TeX(以及其他)was discussed in the Marpa community提供更好的语法前端。
更新:提问者的评论
这个语法(在Marpa SLIF DSL中,||表示优先级较低)
x ::= a
|| x '+' x
| x '+' '"' x '"'
| '"' x '"' '+' x
| '"' x '"' '+' '"' x '"'
|| x x
明确地解析除"a+a"+"a+a"
之外的问题中的输入,其中可能需要"x"
替代(这将使语法模糊不清,正如rici在下面的评论中有用的建议,更多关于下一段):code,output。
x ::= a
|| '"' x '"' assoc => group
|| x '+' x
|| x '.' x
更新1 :
# input: "a+a"+"a+a"
Setting trace_terminals option
Lexer "L0" accepted lexeme L1c1 e1: '"'; value="""
Lexer "L0" accepted lexeme L1c1 e1: '"'; value="""
Lexer "L0" accepted lexeme L1c2 e2: a; value="a"
Lexer "L0" accepted lexeme L1c3 e3: '+'; value="+"
Lexer "L0" accepted lexeme L1c3 e3: '+'; value="+"
Lexer "L0" accepted lexeme L1c4 e4: a; value="a"
Lexer "L0" accepted lexeme L1c5 e5: '"'; value="""
Lexer "L0" accepted lexeme L1c5 e5: '"'; value="""
Lexer "L0" accepted lexeme L1c6 e6: '+'; value="+"
Lexer "L0" accepted lexeme L1c6 e6: '+'; value="+"
Lexer "L0" accepted lexeme L1c7 e7: '"'; value="""
Lexer "L0" accepted lexeme L1c8 e8: a; value="a"
Error in SLIF parse: No lexeme found at line 1, column 9
* String before error: "a+a"+"a
* The error was at line 1, column 9, and at character 0x002b '+', ...
* here: +a"
Marpa::R2 exception at C:\cygwin\home\Ruslan\Marpa-R2-work\q27655176.t line 63.
Progress report is:
F3 @7-8 L1c7-8 x -> a .
R7:6 @0-8 L1c1-8 x -> '"' x '"' '+' '"' x . '"'
# ast dump:
undef