2

这是我正在研究的语法的一部分,用于开发一个解析器工具,这对我的研究很重要。它在 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(通信顺序过程)的过程建模语言,所以是的,这是一个现有语言。由于正在开发中的语言,它现在在学术界使用。我有该语言的 EBNF,我正在尝试将 EBNF 翻译成 ANTLR 中的语法。我已经设法使以下两条规则起作用。但cspaction似乎很难。

paraction : (decl '\circspot' (paraction)+ | action)  ;
action  : ((schemaexp | command | N | cspaction)('[' IDENT+ ':=' exp+']')?)* ;

反斜杠是乳胶的一部分,现在可以省略,因为它们用作字符串。请在下面找到 Circus 的完整 EBNF。它来自已发表的论文,马戏团的指称语义

马戏团的完整 EBNF - http://www.use.com/b1ad2df0609961615fff

4

1 回答 1

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]+;

这与您发布的链接非常相​​似。

像这样生成一个词法分析器和解析器:

java -cp antlr-4.0-complete.jar org.antlr.v4.Tool Circus.g4

请注意,如果要匹配文字反斜杠,则需要对其进行转义:

CIRCSPOT : '\\circspot';
于 2013-02-05T10:31:00.510 回答