标签: left-recursion

解决antlr离开递归

我正在尝试使用ANTLR解析语言,该语句可以包含以下语法:

someVariable, somVariable.someMember, functionCall(param).someMember,  foo.bar.baz(bjork).buffalo().xyzzy
Run Code Online (Sandbox Code Playgroud)

这是我到目前为止提出的ANTLR语法,并access_operation抛出了错误

The following sets of rules are mutually left-recursive [access_operation, expression]:

grammar Test;

options { 
  output=AST;
  ASTLabelType=CommonTree; 
}

tokens {
  LHS;
  RHS;
  CALL;
  PARAMS;
}

start   
  :  body? EOF
  ;

body
  : expression (',' expression)*
  ;

expression
  : function -> ^(CALL)
  | access_operation
  | atom
  ;

access_operation
  : (expression -> ^(LHS)) '.'! (expression -> ^(RHS))
  ;

function
  : (IDENT '(' body? ')') -> ^(IDENT PARAMS?) 
  ;         

atom
  : IDENT
  | NUMBER
  ; …
Run Code Online (Sandbox Code Playgroud)

antlr left-recursion

5
推荐指数
1
解决办法
3399
查看次数

如何删除左递归

我想制作一个允许curried函数调用的语法.

那是:

a() /// good
a()() /// good
a()()() /// good
a(a) /// good
a(a()()) /// good
/// etc
Run Code Online (Sandbox Code Playgroud)

我的第一个刺是这样的:

ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;

fncall  :   expr '(' (expr (',' expr)*)? ')';

expr    :   ID|fncall;
Run Code Online (Sandbox Code Playgroud)

但由于左递归而失败.

recursion antlr antlr3 left-recursion

5
推荐指数
1
解决办法
299
查看次数

如何避免ANTLR 4中的相互左递归

我正在写一个语法来处理标量和向量表达式.下面的语法被简化以显示我所遇到的问题,其中标量表达式可以从向量导出,并且向量可以从标量导出.例如,矢量可以是文字[1, 2, 3]或标量和矢量2 * [1, 2, 3](相当于[2, 4, 6])的乘积.标量可以是文字2或向量的索引[1, 2, 3][1](相当于2).

grammar LeftRecursion;

Integer
    : [0-9]+
    ;

WhiteSpace
    : [ \t\r\n]+ -> skip
    ;

input
    : expression EOF;

expression
    : scalar
    | vector
    ;

scalar
    : Integer
    | vector '[' Integer ']'
    ;

vector
    : '[' Integer ',' Integer ',' Integer ']'
    | scalar '*' vector
    ;
Run Code Online (Sandbox Code Playgroud)

ANTLR4给了我错误:The following sets of rules are mutually left-recursive [scalar, vector] …

left-recursion antlr4

5
推荐指数
1
解决办法
4549
查看次数

为什么右递归解析器不会无限循环?

左递归将使解析器进入无限循环。那么为什么右递归不会发生同样的情况呢?

compiler-construction parsing left-recursion

5
推荐指数
1
解决办法
974
查看次数

从CFG中删除左递归

以下语法已经离开了递归:

T -> Tx | TYx | YX | x
X -> xx
Y -> Yy | Yx | y
Run Code Online (Sandbox Code Playgroud)

你如何去除左递归.我阅读了维基百科的解释,但我对CFG很新,所以它没有多大意义.任何帮助表示赞赏?一个简单的英语解释将更加赞赏.

recursion context-free-grammar left-recursion

4
推荐指数
1
解决办法
4630
查看次数

英语约束免费语法序言

我试图在prolog中实现一个非常简单的约束自由语法时遇到了无限递归问题.

这是我的规则:(vp - >动词短语,np - >名词短语,ap - > adj短语,pp - >预备短语)

    verb(S) :- member(S, [put,  pickup, stack, unstack]).
    det(S) :- member(S, [the]).
    adj(S) :- member(S, [big, small, green, red, yellow, blue]).
    noun(S) :- member(S, [block, table]).
    prep(S) :- member(S, [on, from]).

    vp([V|R]) :- verb(V), pp(PP), np(NP), append(NP, PP, R).
    np([D, N]) :- det(D), noun(N).
    np([D|R]) :- det(D), ap(AP), noun(N), append(AP, [N], R).
    ap([A]) :- adj(A).
    ap([A|R]) :- adj(A), ap(R).
    pp([P|R]) :- prep(P), np(R).
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是ap的规则可以产生任意长的形容词串,所以在某些时候,我试图通过尝试所有这些无限的可能性来试图满足查询.

例如,以下查询将永远不会产生S = [put,the,red,block,on,the,green,block],因为它会首先将左侧"红色"上的形容词短语扩展为无限可能性,然后再尝试对.

?- …
Run Code Online (Sandbox Code Playgroud)

prolog infinite-loop left-recursion dcg failure-slice

4
推荐指数
1
解决办法
393
查看次数

将语法生成翻译成Parsec

我正在尝试转换以下语法生成

callExpr:
    primaryExpr
  | callExpr primaryExpr
Run Code Online (Sandbox Code Playgroud)

到Haskell中的Parsec表达式.

显然问题是它是左递归的,所以我试图解析它的递归 - 上升风格.我试图实现的伪代码是:

e = primaryExp
while(true) {
    e2 = primaryExp
    if(e2 failed) break;
    e = CallExpr(e, e2)
}
Run Code Online (Sandbox Code Playgroud)

我试图将其翻译成Haskell是:

callExpr :: IParser Expr
callExpr = do
    e <- primaryExpr
    return $ callExpr' e
  where
    callExpr' e = do
        e2m <- optionMaybe primaryExpr
        e' <- maybe e (\e2 -> callExpr' (CallExpr e e2)) e2m
        return e'
Run Code Online (Sandbox Code Playgroud)

其中primaryExprtype IParser Expr 和IParser定义为

type IParser a = ParsecT String () (State SourcePos) a
Run Code Online (Sandbox Code Playgroud)

但是这会给我以下类型错误: …

parsing haskell functional-programming parsec left-recursion

4
推荐指数
1
解决办法
140
查看次数

左联想与左递归

我正在尝试为C编写一个编译器(虽然简单的语法).

有些事情我已经坚持了一段时间.如果我没有正确理解,所有二进制操作都是关联的.因此,如果我们有"x + y + z",则首先出现x + y,然后出现加号z.

但是,不执行左关联会导致无限左递归吗?

到目前为止,我检查过的所有解决方案都是左关联的,或者没有左递归,但不是两者都有.是否可以使用具有这两种属性的语法.它甚至可能吗?

例:

左联想:

Expr = Term | Expr + Term
Term = Element | Term ? Element
Element = x|y|z|(Expr)
Run Code Online (Sandbox Code Playgroud)

左递归消除:

Expr = Term ExprTail
ExprTail = epsilon | + Term ExprTail

Term = Element TermTail
TermTail = epsilon | * Element TermTail

Element = x|y|z|(Expr)
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

compiler-construction grammar parsing left-recursion

4
推荐指数
1
解决办法
1744
查看次数

求和型无限递归中左递归语法的解析

我正在尝试从ML 中的现代编译器实现为 Tiger 语言编写一个解析器,但陷入了其中一种递归类型。

我有以下类型

data LValue =                                                                                                                       
    Id Atom                                                                                                                         
    | RecordAccess LValue Atom                                                                                                      
    | ArraySubscript LValue Expression  
Run Code Online (Sandbox Code Playgroud)

具有以下语法:

lvalue -> id
       -> lvalue.id
       -> lvalue[exp]
id -> atom
exp -> (the big, overarching, everything-is-an-expression type)
Run Code Online (Sandbox Code Playgroud)

我试图用秒差距解析它,但我陷入了无限递归循环。这是我当前的基本解析器:

lvalueParser :: Parsec String () LValue                                                                                             
lvalueParser =                                                                                                                      
    try (Id <$> (atomParser <* (notFollowedBy (char '.'))))                                                                         
    <|> try recordAccessParser                                                                                                      
    where recordAccessParser = (uncurry RecordAccess) <$> do {                                                                      
      record <- lvalueParser;                                                                                                         
      char '.';                                                                                                                     
      atom <- atomParser;                                                                                                           
      return (record, atom)                                                                                                      
      }
Run Code Online (Sandbox Code Playgroud)

(注意:我还没有尝试实现任何处理该ArrayAccess部分的方法) …

parsing haskell parsec left-recursion

4
推荐指数
1
解决办法
1190
查看次数

为什么在尝试将字符串添加到该字符串末尾时haskell停止?

我试图在Haskell的字符串末尾添加一个字符串。

    albumStr = ""
main = do
 let albumStr = albumStr ++ "nothing"
 print albumStr
Run Code Online (Sandbox Code Playgroud)

每当我运行它时,它只会卡在控制台中,而我必须终止它。

为什么?以及如何以这种方式将一个字符串添加到另一个字符串?

编辑:如何将多个字符串添加到当前字符串的末尾而不会覆盖它。

谢谢

string haskell infinite-loop accumulate left-recursion

4
推荐指数
2
解决办法
95
查看次数