Reputation: 71
This is part of a grammar I'm working on as to develop a parser tool which will be important in doing my research. It gives me an error under ANTLR IDE In eclipse saying paraction, action, cspaction
are mutually left-recursive.
I've scanned the web for a solution but haven't understood how I might go about it. Since this language is a standard in research arena, I do not have the previledge of changing the semantic details of the language.
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;
I am actually trying to create a grammar file for 'Circus', which is a state rich formal modelling language which is a combination of a specification language called Z and a process modelling language called CSP(Communicating Sequential Process), so yes this is an existing language. Its used in academia for now since the language in under development. I have a EBNF of the language and I'm trying to translate the EBNF to grammar in ANTLR. i've managed to get the following two rules work. But cspaction
seems to be a difficult one.
paraction : (decl '\circspot' (paraction)+ | action) ;
action : ((schemaexp | command | N | cspaction)('[' IDENT+ ':=' exp+']')?)* ;
The backslashes are part of latex, which can be omitted for now since those are used as strings. Below pls find the full EBNF of Circus. Its from the published paper, A Denotational Semantics for Circus.
FULL EBNF of Circus - http://www.use.com/b1ad2df0609961615fff
Upvotes: 2
Views: 1300
Reputation: 170288
I recommend you to go with ANTLR v4. The previous version of ANTLR, v3, does not support left recursion (neither indirect nor direct)., but ANTLR v4 does support direct left recursion. So after eliminating the indirect left recursive rules, and removing the production ParAction
, which is just (Decl '•')* Action
, I ended up with the following grammar:
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]+;
which is very similar to the one you posted a link to.
Generate a lexer and parser like this:
java -cp antlr-4.0-complete.jar org.antlr.v4.Tool Circus.g4
Note that is you want to match a literal backslash, you need to escape it:
CIRCSPOT : '\\circspot';
Upvotes: 2