我正在尝试使用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) 我想制作一个允许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)
但由于左递归而失败.
我正在写一个语法来处理标量和向量表达式.下面的语法被简化以显示我所遇到的问题,其中标量表达式可以从向量导出,并且向量可以从标量导出.例如,矢量可以是文字[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] …
左递归将使解析器进入无限循环。那么为什么右递归不会发生同样的情况呢?
以下语法已经离开了递归:
T -> Tx | TYx | YX | x
X -> xx
Y -> Yy | Yx | y
Run Code Online (Sandbox Code Playgroud)
你如何去除左递归.我阅读了维基百科的解释,但我对CFG很新,所以它没有多大意义.任何帮助表示赞赏?一个简单的英语解释将更加赞赏.
我试图在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) 我正在尝试转换以下语法生成
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
我正在尝试为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)
有任何想法吗?
我正在尝试从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部分的方法) …
我试图在Haskell的字符串末尾添加一个字符串。
albumStr = ""
main = do
let albumStr = albumStr ++ "nothing"
print albumStr
Run Code Online (Sandbox Code Playgroud)
每当我运行它时,它只会卡在控制台中,而我必须终止它。
为什么?以及如何以这种方式将一个字符串添加到另一个字符串?
编辑:如何将多个字符串添加到当前字符串的末尾而不会覆盖它。
谢谢