Parsing LR(0)解析器中的后缀和右关联运算符

Parsing LR(0)解析器中的后缀和右关联运算符,parsing,lexer,lr,associativity,postfix-operator,Parsing,Lexer,Lr,Associativity,Postfix Operator,是否有可能构造一个LR(0)解析器来解析同时使用前缀和后缀运算符的语言?例如,如果我的语法中有+(加法)和!(阶乘)运算符的优先级通常为1+3!应该是1+3!=1+6=7,但如果解析器是LR(0),那么当堆栈上有1+3时,它会减少而不是移位吗 另外,右关联运算符是否会造成问题?例如,2^3^4应该是2^(3^4),但同样,当解析器在堆栈上有2^3时,它如何知道减少或移位 如果这是不可能的,是否还有一种方法可以使用LR(0)解析器,可以通过改变语法在适当的位置添加括号?LR(0)解析器有一个弱点,

是否有可能构造一个LR(0)解析器来解析同时使用前缀和后缀运算符的语言?例如,如果我的语法中有+(加法)和!(阶乘)运算符的优先级通常为1+3!应该是1+3!=1+6=7,但如果解析器是LR(0),那么当堆栈上有1+3时,它会减少而不是移位吗

另外,右关联运算符是否会造成问题?例如,2^3^4应该是2^(3^4),但同样,当解析器在堆栈上有2^3时,它如何知道减少或移位

如果这是不可能的,是否还有一种方法可以使用LR(0)解析器,可以通过改变语法在适当的位置添加括号?

LR(0)解析器有一个弱点,即它们只能解析没有前缀的语言,即语言中没有字符串作为任何其他语言前缀的语言。这通常会使解析这样的表达式变得有点棘手,因为5是5!的前缀!。这也解释了为什么很难获得正确的关联运算符-给定一个类似于

→ F | F^S

解析器在看到一个F之后会有一个shift/reduce冲突,因为它无法判断是扩展它还是再次reduce。这与前面提到的无前缀属性有关

LR(0)的这一弱点是人们在实践中很少使用它的原因之一。SLR(1)和LALR(1)解析器通常可以解析这些语法,因为它们有一个先行标记,让它们决定是移位还是缩减。在上述情况下,解析器不会遇到shift/reduce冲突,因为在决定是否减少F或shift a^时,他们可以看到移位^,因为s后面没有正确的字符串,^。LR(0)解析器的弱点在于,他们只能解析无前缀的语言,语言中没有字符串作为任何其他语言的前缀。这通常会使解析这样的表达式变得有点棘手,因为5是5!的前缀!。这也解释了为什么很难获得正确的关联运算符-给定一个类似于

→ F | F^S

解析器在看到一个F之后会有一个shift/reduce冲突,因为它无法判断是扩展它还是再次reduce。这与前面提到的无前缀属性有关


LR(0)的这一弱点是人们在实践中很少使用它的原因之一。SLR(1)和LALR(1)解析器通常可以解析这些语法,因为它们有一个先行标记,让它们决定是移位还是缩减。在上述情况下,解析器不会遇到shift/reduce冲突,因为在决定是否减少F或shift a^时,他们可以看到移位^,因为s后面没有正确的字符串,a^应该出现在s后面。

RE last段落:有点鸡蛋问题,因为您需要一个能够处理这些结构的解析器(如果是LR(0)不能)知道表达式的RPN形式是什么,或者显式括号可以(应该)在哪里插入时不改变其含义。@Deln这是一个很好的观点。不过,关于方括号,是否可以修改语法以将方括号放在有用的位置?关于最后一段:有点鸡蛋问题,因为您需要一个能够处理这些构造的解析器(如果LR(0)不能)要知道表达式的RPN形式是什么,或者可以(应该)在不改变含义的情况下插入显式括号。@Deln这是一个很好的观点。尽管关于括号,如何可能改变语法以将括号放在有用的位置?