这是我正在研究的语法的一部分,用于开发解析器工具,这对我的研究非常重要。它在ANTLR IDE下给出了一个错误在eclipse中paraction, action, cspaction
是相互左递归的。
我已经在网上搜索了一个解决方案,但还没有理解我会怎么做。由于这种语言是研究领域的标准,我没有改变语言语义细节的普遍性。
paraction : action | decl '\circspot' paraction;
action : schemaexp | command | INDEX | cspaction | action '['INDEX+ ':=' exp+']';
cspaction : 'Skip'|'Stop'|'Chaos'|comm '\circthen' action | pred '&' action
|action ';' action | action '\extchoice' action | action '\intchoice' action
|action '\lpar' nsexp | csexp | nsexp '\rpar' action
|action '\lpar' nsexp | nsexp '\rpar' action
|action '\\' csexp | paraction '('exp+')' | '\circmu' INDEX '\circspot' action
| ';' decl '\circspot' action | 'extchoice' decl '\circspot' action
| '\intchoice' decl '\circspot' action
| '\lpar' csexp '\rpar' decl '\circspot' '\lpar' nsexp '\rpar' '\circspot' action
| '\interleave' decl '\circspot' '\lpar' nsexp '\rpar' action;
我实际上正在尝试为'Circus'创建一个语法文件,这是一种状态丰富的正式建模语言,它是一种称为Z的规范语言和一种称为CSP(Communicating Sequential Process)的流程建模语言的组合,所以是的这是一种现有的语言。它现在用于学术界,因为正在开发中的语言。我有一个语言的EBNF,我正在尝试将EBNF翻译成ANTLR中的语法。我设法让以下两条规则奏效。但是cspaction
似乎很难。
paraction : (decl '\circspot' (paraction)+ | action) ;
action : ((schemaexp | command | N | cspaction)('[' IDENT+ ':=' exp+']')?)* ;
反斜杠是乳胶的一部分,现在可以省略,因为它们用作字符串。下面请找到马戏团的完整EBNF。它来自已发表的论文A Denotational Semantics for Circus。
马戏团的全部EBNF - http://www.use.com/b1ad2df0609961615fff
答案 0 :(得分:2)
我建议你使用ANTLR v4。以前版本的ANTLR v3不支持左递归(既不是间接递归也不是直接递归),但ANTLR v4 支持支持直接左递归。因此,在消除间接左递归规则并删除仅ParAction
的生成(Decl '•')* Action
之后,我最终得到了以下语法:
grammar Circus;
// parser rules
program
: circus_par* EOF
;
circus_par
: par
| CHANNEL cdecl
| CHANSET n '==' csexp
| proc_decl
;
cdecl
: simple_cdecl (';' simple_cdecl)*
;
simple_cdecl
: n+ ':' exp
| n+
| '[' n+ ']' n+ ':' exp
| schema_exp
;
proc_decl
: PROCESS n '[' n+ ']' '^=' proc_def
| PROCESS n '^=' proc_def
;
proc_def
: decl '•' proc_def
| decl '⊙' proc_def
| proc
;
proc
: BEGIN ppar* STATE schema_exp ppar* '•' action END
| proc ';' proc
| proc '□' proc
| proc '⊓' proc
| proc '|[' csexp ']|' proc
| proc '|||' proc
| proc '\\' proc
| '(' decl '•' proc_def ')' '(' exp+ ')'
| n '(' exp+ ')'
| '(' decl '⊙' proc_def ')' '⌊' exp+ '⌋'
| n '⌊' exp+ '⌋'
| proc '[' n+ ':=' n+ ']'
| n '[' exp+ ']'
| ';' decl '•' proc
| '□' decl '•' proc
| '⊓' decl '•' proc
;
ppar
: par
| n '^=' (decl '•')* action
| NAMESET n '==' nsexp
;
action
: schema_exp
| command
| n
| action '[' n+ ':=' exp+ ']'
| SKIP
| STOP
| CHAOS
| comm '→' action
| pred '&' action
| action ';' action
| action '□' action
| action '⊓' action
| action '[|' nsexp
| csexp
| nsexp ']|' action
| action '||[' nsexp
| nsexp ']||' action
| action '\\' csexp
| (decl '•')+ action '(' exp+ ')'
| action '(' exp+ ')'
| 'μ' n '•' action
| ';' decl '•' action
| '□' decl '•' action
| '⊓' decl '•'
| '|[' csexp ']|' decl '•' '|[' nsexp ']|' '•' action
| '|||' decl '•' '|[' nsexp ']|' action
;
comm
: n '[' exp+ ']' cparameter*
| n cparameter*
;
cparameter
: '?' n ':' pred
| '?' n
| '!' exp
| '.' exp
;
command
: n+ ':=' exp+
| IF gactions FI
| n+ ':' '[' pred ',' pred ']'
| '[' pred ']'
| '{' pred '}'
| VAR decl '•' action
| VAL decl '•' action
| RES decl '•' action
| VRES decl '•' action
;
gactions
: pred '→' action '□' gactions
| pred '→' action
;
n
: ZID
;
par : 'TODO';
decl : 'TODO';
nsexp : 'TODO';
exp : 'TODO';
csexp : 'TODO';
schema_exp : 'TODO';
pred : 'TODO';
// lexer rules
CHANNEL : 'channel';
CHANSET : 'chanset';
PROCESS : 'process';
BEGIN : 'begin';
END : 'end';
STATE : 'state';
NAMESET : 'nameset';
SKIP : 'Skip';
STOP : 'Stop';
CHAOS : 'Chaos';
IF : 'if';
FI : 'fi';
VAL : 'val';
VAR : 'var';
RES : 'res';
VRES : 'vres';
ZID : [a-zA-Z]+;
与the one you posted a link to非常相似。
生成一个像这样的词法分析器和解析器:
java -cp antlr-4.0-complete.jar org.antlr.v4.Tool Circus.g4
请注意,您希望匹配文字反斜杠,您需要将其转义:
CIRCSPOT : '\\circspot';