Xtext :确定何时必须调用可选的
Xtext : identify when a optional must be call
我正在使用 xtext 来定义语法。
我对运行时语法评估有疑问。
规则是签名声明。完整语法在这里:
// automatically generated by Xtext
grammar org.xtext.alloy.Alloy with org.eclipse.xtext.common.Terminals
import "http://fr.cuauh.als/1.0"
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
//specification ::= [module] open* paragraph*
//ok
Specification returns Specification:
{Specification}
(module=Module)?
(opens+=Library (opens+=Library)*)?
(paragraphs+=Paragraph (paragraphs+=Paragraph)*)?;
//module ::= "module" name [ "[" ["exactly"] name ("," ["exactly"] num)* "]" ]
//module ::= "module" name? [ "[" ["exactly"] name ("," ExactlyNum )* "]" ]
//ok
Module returns Module:
{Module}
'module' (name=IDName)? ('['(exactly?='exactly')? extensionName=[IDref] (nums+=ExactlyNums ( "," nums+=ExactlyNums)*)?']')?
;
IDName returns IDName:
name=ID
;
terminal ID : '^'?('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|'/')*;
//open ::= ["private"] "open" name [ "[" ref,+ "]" ] [ "as" name ]
//open ::= ["private"] "open" path [ "[" ref,+ "]" ] [ "as" name ]
//ok
Library returns Library:
{Library}
(private?='private')? 'open' path=EString ('['references+=Reference (',' references+=Reference)*']')? ('as' alias=Alias)?
;
//a path
//ok
//terminal PATH returns ecore::EString :
// ('a'..'z'|'A'..'Z'|'_'|'.')+('/'('a'..'z'|'A'..'Z'|'_'|'.')+)*
//;
//paragraph ::= factDecl | assertDecl | funDecl | cmdDecl | enumDecl | sigDecl
//paragraph ::= factDecl | assertDecl | funDecl | predDecl | cmdDecl | enumDecl | sigDecl
//ok
Paragraph returns Paragraph:
FactDeclaration | AssertDeclaration | FunctionDeclaration | PredicatDeclaration | CmdDeclaration | EnumerationDeclaration | SignatureDeclaration;
//cmdDecl ::= [name ":"] ("run"|"check") (name|block) scope
//cmdDecl ::= [name ":"] command (ref|block) scope ["expect (0|1)"]
//ok
CmdDeclaration returns CmdDeclaration:
(name=IDName ':')? operation=cmdOp referenceOrBlock=ReferenceOrBlock (scope=Scope)? (expect?='expect' expectValue=EInt)?;
//ok
ReferenceOrBlock returns ReferenceOrBlock:
BlockExpr | ReferenceName;
//sigDecl ::= sigQual* "sig" name,+ [sigExt] "{" decl,* "}" [block]
//sigDecl ::= ["private"] ["abstract"] [quant] "sig" name [sigExt] "{" relDecl,* "}" [block]
//ok
SignatureDeclaration returns SignatureDeclaration:
{SignatureDeclaration}
(isPrivate?='private')? (isAbstract?='abstract')? (quantifier=SignatureQuantifier)? 'sig' name=IDName (extension=SignatureExtension)? '{'
(relations+=RelationDeclaration ( ',' =>relations+=RelationDeclaration)* )?
'}'
(block=Block)?;
//ok
SignatureExtension returns SignatureExtension:
SignatureinInheritance | SignatureInclusion;
TypeScopeTarget returns TypeScopeTarget:
Int0 | Seq | ReferenceName;
//name ::= ("this" | ID) ["/" ID]*
//ok do not need to be part of the concrete syntax
//Name returns Name:
// thisOrId=ThisOrID ('/'ids+=ID0( "/" ids+=ID0)*)?;
//ok do not need to be part of the concrete syntax
//ThisOrID returns ThisOrID:
// ID0 | This;
EBoolean returns ecore::EBoolean:
'true' | 'false';
//["exactly"] num
//ok
ExactlyNums returns ExactlyNums:
exactly?='exactly' num=Number;
//ok do not need to be part of the concrete syntax
// IDName | IDref;
IDref returns IDref:
namedElement=[IDName]
;
This returns This:
{This}
'this'
;
EString returns ecore::EString:
STRING | ID;
//ok
EInt returns ecore::EInt:
'-'? INT;
Alias returns Alias:
{Alias}
name=IDName;
//factDecl ::= "fact" [name] block
//ok
FactDeclaration returns FactDeclaration:
'fact' (name=IDName)? block=Block;
//assertDecl ::= "assert" [name] block
//ok
AssertDeclaration returns AssertDeclaration:
'assert' (name=IDName)? block=Block ;
//funDecl ::= ["private"] "fun" [ref "."] name "(" decl,* ")" ":" expr block
//funDecl ::= ["private"] "fun" [ref "."] name "[" decl,* "]" ":" expr block
//funDecl ::= ["private"] "fun" [ref "."] name ":" expr block
//
//funDecl ::= ["private"] "fun" [ref "."] name ["(" paramDecl,* ")" | "[" paramDecl,* "]" ] ":" expr block
//ok
FunctionDeclaration returns FunctionDeclaration:
(private?='private')? 'fun' (reference=[Reference] ".")? name=IDName
('(' (parameters+=ParameterDeclaration ( "," parameters+=ParameterDeclaration)*)? ')'|
'[' (parameters+=ParameterDeclaration ( "," parameters+=ParameterDeclaration)*)? ']')?
':' ^returns=Expression
block=Block;
//funDecl ::= ["private"] "pred" [ref "."] name "(" decl,* ")" block
//funDecl ::= ["private"] "pred" [ref "."] name "[" decl,* "]" block
//funDecl ::= ["private"] "pred" [ref "."] name block
//
//predDecl ::= ["private"] "pred" [ref "."] name ["(" paramDecl,* ")" | "[" paramDecl,* "]" ] ":" block
//ok
PredicatDeclaration returns PredicatDeclaration:
(private?='private')? 'pred' (reference=[Reference|EString] ".")? name=IDName
('(' (parameters+=ParameterDeclaration ( "," parameters+=ParameterDeclaration)*)? ')'|
'[' (parameters+=ParameterDeclaration ( "," parameters+=ParameterDeclaration)*)? ']')?
block=Block;
//enumDecl ::= "enum" name "{" name ("," name)* "}"
//enumDecl ::= "enum" name "{" enumEl ("," enumEl)* "}"
//ok
EnumerationDeclaration returns EnumerationDeclaration:
'enum' name=IDName '{' enumeration+=EnumerationElement ( "," enumeration+=EnumerationElement)* '}';
//ok
EnumerationElement returns EnumerationElement:
{EnumerationElement}
name=IDName;
//"lone" | "one" | "some"
//ok
enum SignatureQuantifier returns SignatureQuantifier:
lone = 'lone' | one = 'one' | some = 'some';
//decl ::= ["private"] ["disj"] name,+ ":" ["disj"] expr
//decl ::= ["private"] ["disj"] name,+ ":" ["disj"] expr
//ok
RelationDeclaration returns RelationDeclaration:
(isPrivate?='private')? (varsAreDisjoint?='disj')? names+=VarDecl (',' names+=VarDecl)* ':' (expressionIsDisjoint?='disj')? expression=Expression;
//sigExt ::= "extends" ref
//ok
SignatureinInheritance returns SignatureinInheritance:
'extends' extends=Reference;
//sigExt ::= "in" ref ["+" ref]*
//ok
SignatureInclusion returns SignatureInclusion:
'in' includes+=Reference ( "+" includes+=Reference)* ;
//ok
VarDecl returns VarDecl:
{VarDecl}
name=IDName;
//decl ::= ["private"] ["disj"] name,+ ":" ["disj"] expr
//ok
ParameterDeclaration returns ParameterDeclaration:
(isPrivate?='private')? (varsAreDisjoint?='disj')? names+=VarDecl ( "," names+=VarDecl)* ':' (expressionIsDisjoint?='disj')? expression=Expression;
//("run"|"check")
//ok
enum cmdOp returns cmdOp:
run = 'run' | check = 'check';
//expr ::=
//1) "let" letDecl,+ blockOrBar
//2) | quant decl,+ blockOrBar
//3) | unOp expr
//4) | expr binOp expr
//5) | expr arrowOp expr
//6) | expr ["!"|"not"] compareOp expr
//7) | expr ("=>"|"implies") expr "else" expr
//8) | expr "[" expr,* "]"
//9) | number
//10) | "-" number
//11) | "none"
//12) | "iden"
//13) | "univ"
//14) | "Int"
//15) | "seq/Int"
//16) | "(" expr ")"
//17) | ["@"] Name
//18) | block
//19) | "{" decl,+ blockOrBar "}"
// expr ::= leftPart [rightPart]
Expression returns Expression:
lhs=NonLeftRecursiveExpression (=>parts=NaryPart)?;
//4) | expr binOp expr
//5) | expr arrowOp expr
//6) | expr ["!"|"not"] compareOp expr
//7) | expr ("=>"|"implies") expr "else" expr
//8) | expr "[" expr,* "]"
//ok
NaryPart returns NaryPart:
BinaryOrElsePart | CallPart;
//4) | expr binOp expr
//5) | expr arrowOp expr
//6) | expr ["!"|"not"] compareOp expr
//7) | expr ("=>"|"implies") expr "else" expr
//
//7) | expr ("=>"|"implies") expr "else" expr
//4)5)6) | expr binaryOperator expr*
//ok
BinaryOrElsePart returns BinaryOrElsePart:
=>('=>'|'implies') rhs=Expression (=>'else' else=Expression)? |
operator=BinaryOperator rhs=Expression ;
//8) | expr "[" expr,* "]"
//it is just the right part
//ok
CallPart returns CallPart:
{CallPart}
'['(params+=Expression ( "," params+=Expression)*)?']';
//1) "let" letDecl,+ blockOrBar
//2) | quant decl,+ blockOrBar
//19) | "{" decl,+ blockOrBar "}"
//18) | block
// | terminalExpression
NonLeftRecursiveExpression returns NonLeftRecursiveExpression:
LetExpression | QuantifiedExpression | CurlyBracketsExpression | BlockExpr | TerminalExpression;
//1) "let" letDecl,+ blockOrBar
//ok
LetExpression returns LetExpression:
'let' letDeclarations+=LetDeclaration ( "," letDeclarations+=LetDeclaration)* blockOrBar=BlockOrBar;
//2) | quant decl,+ blockOrBar
//ok
QuantifiedExpression returns QuantifiedExpression:
quantifier=QuantifiedExpressionQuantifier varDeclaration+=VarDeclaration ( "," varDeclaration+=VarDeclaration)* blockOrBar=BlockOrBar;
//
//binOp ::= "||" | "or" | "&&" | "and" | "&" | "<=>" | "iff" | "=>" | "implies" | "+" | "-" | "++" | "<:" | ":>" | "." | "<<" | ">>" | ">>>"
//compareOp ::= "=" | "in" | "<" | ">" | "=<" | ">="
//arrowOp ::= ["some"|"one"|"lone"|"set"] "->" ["some"|"one"|"lone"|"set"]
//ok
BinaryOperator returns BinaryOperator:
RelationalOperator | CompareOperator | ArrowOperator;
//ok
RelationalOperator returns RelationalOperator:
operator=RelationalOp;
//binOp ::= "||" | "or" | "&&" | "and" | "&" | "<=>" | "iff" | "=>" | "implies" | "+" | "-" | "++" | "<:" | ":>" | "." | "<<" | ">>" | ">>>"
//ok
enum RelationalOp returns RelationalOp:
or = '||' | and = '&&' | union = '+' | intersection = '&' | difference = '-' | equivalence = '<=>' | override = '++'
| domain = '<:' | range = ':>' | join = '.' ; // | lshift = '<<' | rshift = '>>' | rrshift = '>>>';
//["!"|"not"] compareOp
//ok
CompareOperator returns CompareOperator:
(negated?='!' | negated?='not')? operator=CompareOp;
//compareOp ::= "=" | "in" | "<" | ">" | "=<" | ">="
enum CompareOp returns CompareOp:
equal = '=' | inclusion = 'in' | lesser = '<' | greater = '>' | lesserOrEq = '<=' | greaterOrEq = '>=';
//arrowOp ::= ["some"|"one"|"lone"|"set"] "->" ["some"|"one"|"lone"|"set"]
//ok
ArrowOperator returns ArrowOperator:
{ArrowOperator}
(leftQuantifier=ArrowQuantifier)? '->' (=>rightQuantifier=ArrowQuantifier)?;
//"some"|"one"|"lone"|"set"
//ok
enum ArrowQuantifier returns ArrowQuantifier:
lone = 'lone' | one = 'one' | some = 'some' | set = 'set' ;
//19) | "{" decl,+ blockOrBar "}"
//ok
CurlyBracketsExpression returns CurlyBracketsExpression:
'{' varDeclarations+=VarDeclaration ( "," varDeclarations+=VarDeclaration)* blockOrBar=BlockOrBar '}';
//blockOrBar ::= block
//blockOrBar ::= "|" expr
//ok
BlockOrBar returns BlockOrBar:
BlockExpr | Bar;
//blockOrBar ::= "|" expr
//ok
Bar returns Bar:
'|' expression=Expression;
//block ::= "{" expr* "}"
//ok
BlockExpr returns BlockExpr:
{BlockExpr}
'{' (expressions+=Expression ( "," expressions+=Expression)*)?'}';
//3) unOp expr
// | finalExpression
TerminalExpression returns TerminalExpression:
UnaryExpr | finalExpression ;
//3) unOp expr
//ok
UnaryExpr returns UnaryExpr:
unOp=UnaryOperator expression=TerminalExpression;
//unOp ::= "!" | "not" | "no" | "some" | "lone" | "one" | "set" | "seq" | "#" | "~" | "*" | "^"
//unOp ::= "!" | "not" |"#" | "~" | "*" | "^"
//ok
enum UnaryOperator returns UnaryOperator:
not = 'not' | card = '#' | transpose = '~' | reflexiveClosure = '*' | closure = '^' | not2 = '!';
//16) | "(" expr ")"
//9) | number
//10) | "-" number
//17) | ["@"] Name
//11) | "none"
//12) | "iden"
//13) | "univ"
//14) | "Int"
//15) | "seq/Int"
//16) | "(" expr ")"
//10) | ["-"] number
//17) | "@" Name
//17) | reference
//12)13) | constante
finalExpression returns TerminalExpression:
BracketExpression | NumberExpression | NotExpandedExpression | ReferenceExpression | ConstantExpression;
//16) | "(" expr ")"
//ok
BracketExpression returns BracketExpression:
'('expression=Expression')';
//9) | number
//10) | "-" number
//ok
Number returns Number:
NumberExpression;
//ok
NumberExpression returns NumberExpression:
value=EInt;
//17) | ["@"] Name
//17) | "@" Name
//ok
NotExpandedExpression returns NotExpandedExpression:
'@' name=[IDref];
//ok
ReferenceExpression returns ReferenceExpression:
reference=Reference;
//ref ::= name | "univ" | "Int" | "seq/Int"
//ok
Reference returns Reference:
ReferenceName | ConstanteReference;
//ok
ConstanteReference returns ConstanteReference:
cst=constanteRef;
//13) | "univ"
//14) | "Int"
//15) | "seq/Int"
//ok
enum constanteRef returns constanteRef:
int = 'Int' | seqint = 'seq/Int' | univ = 'univ';
//ok
ReferenceName returns ReferenceName:
name=IDref;
//ok
ConstantExpression returns ConstantExpression:
constante=Constant;
//11) | "none"
//12) | "iden"
//ok
enum Constant returns Constant:
none = 'none' | iden = 'iden';
//ok
Block returns Block:
BlockExpr;
//letDecl ::= name "=" expr
//ok
LetDeclaration returns LetDeclaration:
varName=VarDecl '=' expression=Expression;
//quant ::= "all" | "no" | "some" | "lone" | "one" | "sum"
//quant ::= "all" | "no" | "some" | "lone" | "one" | "null"
//ok
enum QuantifiedExpressionQuantifier returns QuantifiedExpressionQuantifier:
no = 'no' | one = 'one' | lone = 'lone' | some = 'some' | all = 'all' | null = 'null';
//decl ::= ["private"] ["disj"] name,+ ":" ["disj"] expr
//ok
VarDeclaration returns VarDeclaration:
(isPrivate?='private')? (varsAreDisjoint?='disj')? names+=VarDecl ( "," names+=VarDecl)* ':' (expressionIsDisjoint?='disj')? expression=Expression;
//scope ::= "for" number ["expect" (0|1)]
//scope ::= "for" number "but" typescope,+ ["expect" (0|1)]
//scope ::= "for" typescope,+ ["expect" (0|1)]
//scope ::= ["expect" (0|1)]
//
//scope ::= "for" [number] ["but"] typescope,*
//ok
Scope returns Scope:
{Scope}
'for' (number=Number)? (but?='but')? (typeScope+=TypeScope ( "," typeScope+=TypeScope)*)?;
//typescope ::= ["exactly"] number [name|"int"|"seq"]
//typescope ::= ExactlyNumber target
TypeScope returns TypeScope:
num=ExactlyNums target=[TypeScopeTarget];
//[name|"int"|"seq"]
//[Validname|"int"|"seq"]
//ok
TypeScopeTarget_Impl returns TypeScopeTarget:
{TypeScopeTarget}
;
Int0 returns Int:
{Int}
'Int'
;
Seq returns Seq:
{Seq}
'Seq'
;
但是在编辑器的运行时,我在小例子中有以下错误:
sig A {}
sig B {
a : A
}
Multiple markers at this line (line a : A)
- no viable alternative at input 'A'
- missing EOF at '->'
- missing '}' at 'a'
该规则适用于第一个,但不适用于第二个。预计括号之间没有关系声明。
我认为这是由于使用以下形式调用规则 relationDeclaration 的声明:
(relations+=RelationDeclaration ( ',' relations+=RelationDeclaration)*)?
我不明白哪里出了问题。
我错过了什么?
我该怎么做才能让它发挥作用?
提前致谢。
在你的 RelationDeclaration
语法中,你似乎错过了一些可选的标记问号 (isPrivate?='private')? (varsAreDisjoint?='disj')?
(同样的问题遍布整个语法)
?=
将属性声明为可选的,但只有围绕规则调用的 ?
使其实际上是可选的
我正在使用 xtext 来定义语法。 我对运行时语法评估有疑问。
规则是签名声明。完整语法在这里:
// automatically generated by Xtext
grammar org.xtext.alloy.Alloy with org.eclipse.xtext.common.Terminals
import "http://fr.cuauh.als/1.0"
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
//specification ::= [module] open* paragraph*
//ok
Specification returns Specification:
{Specification}
(module=Module)?
(opens+=Library (opens+=Library)*)?
(paragraphs+=Paragraph (paragraphs+=Paragraph)*)?;
//module ::= "module" name [ "[" ["exactly"] name ("," ["exactly"] num)* "]" ]
//module ::= "module" name? [ "[" ["exactly"] name ("," ExactlyNum )* "]" ]
//ok
Module returns Module:
{Module}
'module' (name=IDName)? ('['(exactly?='exactly')? extensionName=[IDref] (nums+=ExactlyNums ( "," nums+=ExactlyNums)*)?']')?
;
IDName returns IDName:
name=ID
;
terminal ID : '^'?('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|'/')*;
//open ::= ["private"] "open" name [ "[" ref,+ "]" ] [ "as" name ]
//open ::= ["private"] "open" path [ "[" ref,+ "]" ] [ "as" name ]
//ok
Library returns Library:
{Library}
(private?='private')? 'open' path=EString ('['references+=Reference (',' references+=Reference)*']')? ('as' alias=Alias)?
;
//a path
//ok
//terminal PATH returns ecore::EString :
// ('a'..'z'|'A'..'Z'|'_'|'.')+('/'('a'..'z'|'A'..'Z'|'_'|'.')+)*
//;
//paragraph ::= factDecl | assertDecl | funDecl | cmdDecl | enumDecl | sigDecl
//paragraph ::= factDecl | assertDecl | funDecl | predDecl | cmdDecl | enumDecl | sigDecl
//ok
Paragraph returns Paragraph:
FactDeclaration | AssertDeclaration | FunctionDeclaration | PredicatDeclaration | CmdDeclaration | EnumerationDeclaration | SignatureDeclaration;
//cmdDecl ::= [name ":"] ("run"|"check") (name|block) scope
//cmdDecl ::= [name ":"] command (ref|block) scope ["expect (0|1)"]
//ok
CmdDeclaration returns CmdDeclaration:
(name=IDName ':')? operation=cmdOp referenceOrBlock=ReferenceOrBlock (scope=Scope)? (expect?='expect' expectValue=EInt)?;
//ok
ReferenceOrBlock returns ReferenceOrBlock:
BlockExpr | ReferenceName;
//sigDecl ::= sigQual* "sig" name,+ [sigExt] "{" decl,* "}" [block]
//sigDecl ::= ["private"] ["abstract"] [quant] "sig" name [sigExt] "{" relDecl,* "}" [block]
//ok
SignatureDeclaration returns SignatureDeclaration:
{SignatureDeclaration}
(isPrivate?='private')? (isAbstract?='abstract')? (quantifier=SignatureQuantifier)? 'sig' name=IDName (extension=SignatureExtension)? '{'
(relations+=RelationDeclaration ( ',' =>relations+=RelationDeclaration)* )?
'}'
(block=Block)?;
//ok
SignatureExtension returns SignatureExtension:
SignatureinInheritance | SignatureInclusion;
TypeScopeTarget returns TypeScopeTarget:
Int0 | Seq | ReferenceName;
//name ::= ("this" | ID) ["/" ID]*
//ok do not need to be part of the concrete syntax
//Name returns Name:
// thisOrId=ThisOrID ('/'ids+=ID0( "/" ids+=ID0)*)?;
//ok do not need to be part of the concrete syntax
//ThisOrID returns ThisOrID:
// ID0 | This;
EBoolean returns ecore::EBoolean:
'true' | 'false';
//["exactly"] num
//ok
ExactlyNums returns ExactlyNums:
exactly?='exactly' num=Number;
//ok do not need to be part of the concrete syntax
// IDName | IDref;
IDref returns IDref:
namedElement=[IDName]
;
This returns This:
{This}
'this'
;
EString returns ecore::EString:
STRING | ID;
//ok
EInt returns ecore::EInt:
'-'? INT;
Alias returns Alias:
{Alias}
name=IDName;
//factDecl ::= "fact" [name] block
//ok
FactDeclaration returns FactDeclaration:
'fact' (name=IDName)? block=Block;
//assertDecl ::= "assert" [name] block
//ok
AssertDeclaration returns AssertDeclaration:
'assert' (name=IDName)? block=Block ;
//funDecl ::= ["private"] "fun" [ref "."] name "(" decl,* ")" ":" expr block
//funDecl ::= ["private"] "fun" [ref "."] name "[" decl,* "]" ":" expr block
//funDecl ::= ["private"] "fun" [ref "."] name ":" expr block
//
//funDecl ::= ["private"] "fun" [ref "."] name ["(" paramDecl,* ")" | "[" paramDecl,* "]" ] ":" expr block
//ok
FunctionDeclaration returns FunctionDeclaration:
(private?='private')? 'fun' (reference=[Reference] ".")? name=IDName
('(' (parameters+=ParameterDeclaration ( "," parameters+=ParameterDeclaration)*)? ')'|
'[' (parameters+=ParameterDeclaration ( "," parameters+=ParameterDeclaration)*)? ']')?
':' ^returns=Expression
block=Block;
//funDecl ::= ["private"] "pred" [ref "."] name "(" decl,* ")" block
//funDecl ::= ["private"] "pred" [ref "."] name "[" decl,* "]" block
//funDecl ::= ["private"] "pred" [ref "."] name block
//
//predDecl ::= ["private"] "pred" [ref "."] name ["(" paramDecl,* ")" | "[" paramDecl,* "]" ] ":" block
//ok
PredicatDeclaration returns PredicatDeclaration:
(private?='private')? 'pred' (reference=[Reference|EString] ".")? name=IDName
('(' (parameters+=ParameterDeclaration ( "," parameters+=ParameterDeclaration)*)? ')'|
'[' (parameters+=ParameterDeclaration ( "," parameters+=ParameterDeclaration)*)? ']')?
block=Block;
//enumDecl ::= "enum" name "{" name ("," name)* "}"
//enumDecl ::= "enum" name "{" enumEl ("," enumEl)* "}"
//ok
EnumerationDeclaration returns EnumerationDeclaration:
'enum' name=IDName '{' enumeration+=EnumerationElement ( "," enumeration+=EnumerationElement)* '}';
//ok
EnumerationElement returns EnumerationElement:
{EnumerationElement}
name=IDName;
//"lone" | "one" | "some"
//ok
enum SignatureQuantifier returns SignatureQuantifier:
lone = 'lone' | one = 'one' | some = 'some';
//decl ::= ["private"] ["disj"] name,+ ":" ["disj"] expr
//decl ::= ["private"] ["disj"] name,+ ":" ["disj"] expr
//ok
RelationDeclaration returns RelationDeclaration:
(isPrivate?='private')? (varsAreDisjoint?='disj')? names+=VarDecl (',' names+=VarDecl)* ':' (expressionIsDisjoint?='disj')? expression=Expression;
//sigExt ::= "extends" ref
//ok
SignatureinInheritance returns SignatureinInheritance:
'extends' extends=Reference;
//sigExt ::= "in" ref ["+" ref]*
//ok
SignatureInclusion returns SignatureInclusion:
'in' includes+=Reference ( "+" includes+=Reference)* ;
//ok
VarDecl returns VarDecl:
{VarDecl}
name=IDName;
//decl ::= ["private"] ["disj"] name,+ ":" ["disj"] expr
//ok
ParameterDeclaration returns ParameterDeclaration:
(isPrivate?='private')? (varsAreDisjoint?='disj')? names+=VarDecl ( "," names+=VarDecl)* ':' (expressionIsDisjoint?='disj')? expression=Expression;
//("run"|"check")
//ok
enum cmdOp returns cmdOp:
run = 'run' | check = 'check';
//expr ::=
//1) "let" letDecl,+ blockOrBar
//2) | quant decl,+ blockOrBar
//3) | unOp expr
//4) | expr binOp expr
//5) | expr arrowOp expr
//6) | expr ["!"|"not"] compareOp expr
//7) | expr ("=>"|"implies") expr "else" expr
//8) | expr "[" expr,* "]"
//9) | number
//10) | "-" number
//11) | "none"
//12) | "iden"
//13) | "univ"
//14) | "Int"
//15) | "seq/Int"
//16) | "(" expr ")"
//17) | ["@"] Name
//18) | block
//19) | "{" decl,+ blockOrBar "}"
// expr ::= leftPart [rightPart]
Expression returns Expression:
lhs=NonLeftRecursiveExpression (=>parts=NaryPart)?;
//4) | expr binOp expr
//5) | expr arrowOp expr
//6) | expr ["!"|"not"] compareOp expr
//7) | expr ("=>"|"implies") expr "else" expr
//8) | expr "[" expr,* "]"
//ok
NaryPart returns NaryPart:
BinaryOrElsePart | CallPart;
//4) | expr binOp expr
//5) | expr arrowOp expr
//6) | expr ["!"|"not"] compareOp expr
//7) | expr ("=>"|"implies") expr "else" expr
//
//7) | expr ("=>"|"implies") expr "else" expr
//4)5)6) | expr binaryOperator expr*
//ok
BinaryOrElsePart returns BinaryOrElsePart:
=>('=>'|'implies') rhs=Expression (=>'else' else=Expression)? |
operator=BinaryOperator rhs=Expression ;
//8) | expr "[" expr,* "]"
//it is just the right part
//ok
CallPart returns CallPart:
{CallPart}
'['(params+=Expression ( "," params+=Expression)*)?']';
//1) "let" letDecl,+ blockOrBar
//2) | quant decl,+ blockOrBar
//19) | "{" decl,+ blockOrBar "}"
//18) | block
// | terminalExpression
NonLeftRecursiveExpression returns NonLeftRecursiveExpression:
LetExpression | QuantifiedExpression | CurlyBracketsExpression | BlockExpr | TerminalExpression;
//1) "let" letDecl,+ blockOrBar
//ok
LetExpression returns LetExpression:
'let' letDeclarations+=LetDeclaration ( "," letDeclarations+=LetDeclaration)* blockOrBar=BlockOrBar;
//2) | quant decl,+ blockOrBar
//ok
QuantifiedExpression returns QuantifiedExpression:
quantifier=QuantifiedExpressionQuantifier varDeclaration+=VarDeclaration ( "," varDeclaration+=VarDeclaration)* blockOrBar=BlockOrBar;
//
//binOp ::= "||" | "or" | "&&" | "and" | "&" | "<=>" | "iff" | "=>" | "implies" | "+" | "-" | "++" | "<:" | ":>" | "." | "<<" | ">>" | ">>>"
//compareOp ::= "=" | "in" | "<" | ">" | "=<" | ">="
//arrowOp ::= ["some"|"one"|"lone"|"set"] "->" ["some"|"one"|"lone"|"set"]
//ok
BinaryOperator returns BinaryOperator:
RelationalOperator | CompareOperator | ArrowOperator;
//ok
RelationalOperator returns RelationalOperator:
operator=RelationalOp;
//binOp ::= "||" | "or" | "&&" | "and" | "&" | "<=>" | "iff" | "=>" | "implies" | "+" | "-" | "++" | "<:" | ":>" | "." | "<<" | ">>" | ">>>"
//ok
enum RelationalOp returns RelationalOp:
or = '||' | and = '&&' | union = '+' | intersection = '&' | difference = '-' | equivalence = '<=>' | override = '++'
| domain = '<:' | range = ':>' | join = '.' ; // | lshift = '<<' | rshift = '>>' | rrshift = '>>>';
//["!"|"not"] compareOp
//ok
CompareOperator returns CompareOperator:
(negated?='!' | negated?='not')? operator=CompareOp;
//compareOp ::= "=" | "in" | "<" | ">" | "=<" | ">="
enum CompareOp returns CompareOp:
equal = '=' | inclusion = 'in' | lesser = '<' | greater = '>' | lesserOrEq = '<=' | greaterOrEq = '>=';
//arrowOp ::= ["some"|"one"|"lone"|"set"] "->" ["some"|"one"|"lone"|"set"]
//ok
ArrowOperator returns ArrowOperator:
{ArrowOperator}
(leftQuantifier=ArrowQuantifier)? '->' (=>rightQuantifier=ArrowQuantifier)?;
//"some"|"one"|"lone"|"set"
//ok
enum ArrowQuantifier returns ArrowQuantifier:
lone = 'lone' | one = 'one' | some = 'some' | set = 'set' ;
//19) | "{" decl,+ blockOrBar "}"
//ok
CurlyBracketsExpression returns CurlyBracketsExpression:
'{' varDeclarations+=VarDeclaration ( "," varDeclarations+=VarDeclaration)* blockOrBar=BlockOrBar '}';
//blockOrBar ::= block
//blockOrBar ::= "|" expr
//ok
BlockOrBar returns BlockOrBar:
BlockExpr | Bar;
//blockOrBar ::= "|" expr
//ok
Bar returns Bar:
'|' expression=Expression;
//block ::= "{" expr* "}"
//ok
BlockExpr returns BlockExpr:
{BlockExpr}
'{' (expressions+=Expression ( "," expressions+=Expression)*)?'}';
//3) unOp expr
// | finalExpression
TerminalExpression returns TerminalExpression:
UnaryExpr | finalExpression ;
//3) unOp expr
//ok
UnaryExpr returns UnaryExpr:
unOp=UnaryOperator expression=TerminalExpression;
//unOp ::= "!" | "not" | "no" | "some" | "lone" | "one" | "set" | "seq" | "#" | "~" | "*" | "^"
//unOp ::= "!" | "not" |"#" | "~" | "*" | "^"
//ok
enum UnaryOperator returns UnaryOperator:
not = 'not' | card = '#' | transpose = '~' | reflexiveClosure = '*' | closure = '^' | not2 = '!';
//16) | "(" expr ")"
//9) | number
//10) | "-" number
//17) | ["@"] Name
//11) | "none"
//12) | "iden"
//13) | "univ"
//14) | "Int"
//15) | "seq/Int"
//16) | "(" expr ")"
//10) | ["-"] number
//17) | "@" Name
//17) | reference
//12)13) | constante
finalExpression returns TerminalExpression:
BracketExpression | NumberExpression | NotExpandedExpression | ReferenceExpression | ConstantExpression;
//16) | "(" expr ")"
//ok
BracketExpression returns BracketExpression:
'('expression=Expression')';
//9) | number
//10) | "-" number
//ok
Number returns Number:
NumberExpression;
//ok
NumberExpression returns NumberExpression:
value=EInt;
//17) | ["@"] Name
//17) | "@" Name
//ok
NotExpandedExpression returns NotExpandedExpression:
'@' name=[IDref];
//ok
ReferenceExpression returns ReferenceExpression:
reference=Reference;
//ref ::= name | "univ" | "Int" | "seq/Int"
//ok
Reference returns Reference:
ReferenceName | ConstanteReference;
//ok
ConstanteReference returns ConstanteReference:
cst=constanteRef;
//13) | "univ"
//14) | "Int"
//15) | "seq/Int"
//ok
enum constanteRef returns constanteRef:
int = 'Int' | seqint = 'seq/Int' | univ = 'univ';
//ok
ReferenceName returns ReferenceName:
name=IDref;
//ok
ConstantExpression returns ConstantExpression:
constante=Constant;
//11) | "none"
//12) | "iden"
//ok
enum Constant returns Constant:
none = 'none' | iden = 'iden';
//ok
Block returns Block:
BlockExpr;
//letDecl ::= name "=" expr
//ok
LetDeclaration returns LetDeclaration:
varName=VarDecl '=' expression=Expression;
//quant ::= "all" | "no" | "some" | "lone" | "one" | "sum"
//quant ::= "all" | "no" | "some" | "lone" | "one" | "null"
//ok
enum QuantifiedExpressionQuantifier returns QuantifiedExpressionQuantifier:
no = 'no' | one = 'one' | lone = 'lone' | some = 'some' | all = 'all' | null = 'null';
//decl ::= ["private"] ["disj"] name,+ ":" ["disj"] expr
//ok
VarDeclaration returns VarDeclaration:
(isPrivate?='private')? (varsAreDisjoint?='disj')? names+=VarDecl ( "," names+=VarDecl)* ':' (expressionIsDisjoint?='disj')? expression=Expression;
//scope ::= "for" number ["expect" (0|1)]
//scope ::= "for" number "but" typescope,+ ["expect" (0|1)]
//scope ::= "for" typescope,+ ["expect" (0|1)]
//scope ::= ["expect" (0|1)]
//
//scope ::= "for" [number] ["but"] typescope,*
//ok
Scope returns Scope:
{Scope}
'for' (number=Number)? (but?='but')? (typeScope+=TypeScope ( "," typeScope+=TypeScope)*)?;
//typescope ::= ["exactly"] number [name|"int"|"seq"]
//typescope ::= ExactlyNumber target
TypeScope returns TypeScope:
num=ExactlyNums target=[TypeScopeTarget];
//[name|"int"|"seq"]
//[Validname|"int"|"seq"]
//ok
TypeScopeTarget_Impl returns TypeScopeTarget:
{TypeScopeTarget}
;
Int0 returns Int:
{Int}
'Int'
;
Seq returns Seq:
{Seq}
'Seq'
;
但是在编辑器的运行时,我在小例子中有以下错误:
sig A {}
sig B {
a : A
}
Multiple markers at this line (line a : A)
- no viable alternative at input 'A'
- missing EOF at '->'
- missing '}' at 'a'
该规则适用于第一个,但不适用于第二个。预计括号之间没有关系声明。 我认为这是由于使用以下形式调用规则 relationDeclaration 的声明:
(relations+=RelationDeclaration ( ',' relations+=RelationDeclaration)*)?
我不明白哪里出了问题。 我错过了什么? 我该怎么做才能让它发挥作用?
提前致谢。
在你的 RelationDeclaration
语法中,你似乎错过了一些可选的标记问号 (isPrivate?='private')? (varsAreDisjoint?='disj')?
(同样的问题遍布整个语法)
?=
将属性声明为可选的,但只有围绕规则调用的 ?
使其实际上是可选的