All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ibScenarios.1.7.1.source-code.ScenarioParser.g4 Maven / Gradle / Ivy

parser grammar ScenarioParser;

options { tokenVocab = ScenarioLexer; }

// =============== Scenarios ===============

file: scenario* EOF;

scenario: header sentence*;
header: H1 HEADLINE_TEXT HEADLINE_END;

// --------------- Sentences ---------------

actor: WE | THE? name;

sentence: simpleSentences sentenceEnd
        | compoundSentence sentenceEnd
        | diagramSentence
        | sectionSentence
        | commentSentence
        ;

sentenceEnd: FULL_STOP | {_input.LA(-1) == CODE_BLOCK_END}?;

simpleSentence: thereSentence
              | isSentence
              | areSentence
              | hasSentence
              | expectSentence
              | matchSentence
              | createSentence
              | callSentence
              | answerSentence
              | writeSentence
              | addSentence
              | removeSentence
              ;

simpleSentences: simpleSentence (sep simpleSentence)* (sep compoundSentence)?;

compoundSentence: conditionalSentence
                | takeSentence
                ;

sectionSentence: H2 HEADLINE_TEXT HEADLINE_END;
commentSentence: (LINE_COMMENT | BLOCKQUOTE) HEADLINE_TEXT HEADLINE_END;

codeBlock: CODE_BLOCK CODE_BLOCK_LANGUAGE? CODE_BLOCK_LINE* CODE_BLOCK_END;

// Definition

thereSentence: THERE IS simpleDescriptor
             | THERE ARE multiDescriptor;

simpleDescriptor: (A | AN) typeName name? withClauses? // indefinite form
                | THE typeName name withClauses? // definite form
                ;

multiDescriptor: typesName (name (sep name)+)? withClauses? // indefinite form
               | THE typesName name (sep name)+ withClauses? // definite form
               ;

typeName: simpleName | name CARD;
typesName: simpleName | name CARDS;

isSentence: EVERY typeName IS (A | AN) typeName # InheritanceIsSentence
          | THE? name IS (A | AN) typeName withClauses? # SimpleIsSentence
          ;
areSentence: name (sep name)+ ARE typesName withClauses?;

withClauses: withClause (sep withClause)*;
withClause: WITH namedExpr;

namedExpr: THE? simpleName expr # NamedSimple
         | number name          # NamedNumber
         ;
bidiNamedExpr: firstName=simpleName AND (IS | ARE) (ONE OF)? THE? otherName=simpleName OF (expr | aPlaceholder | manyPlaceholder);

placeholderNamedExpr: (A | AN)? name (likePlaceholder | ofTypePlaceholder);

aPlaceholder: (A | AN) typeName (LIKE expr)?;
manyPlaceholder: MANY typesName (LIKE expr)?;
likePlaceholder: LIKE expr;
ofTypePlaceholder: OF TYPE typeName (LIKE expr)?;
everyPlaceholder: EVERY typeName (LIKE nameAccess)?;

hasSentence: (everyPlaceholder | nameAccess) hasClauses;
hasClauses: hasClause (sep hasClause)*;
hasClause: verb=(HAS | HAVE) (namedExpr | bidiNamedExpr | placeholderNamedExpr);

createSentence: actor verb=(CREATE | CREATES) (simpleDescriptor | multiDescriptor);

callSentence: actor verb=(CALL | CALLS) name (ON expr)? withClauses?;

answerSentence: actor verb=(ANSWER | ANSWERS) WITH expr (INTO THE? name)?;

writeSentence: actor verb=(WRITE | WRITES) expr INTO expr;
addSentence: actor verb=(ADD | ADDS) expr TO expr;
removeSentence: actor verb=(REMOVE | REMOVES) expr FROM expr;

// Compound sentences, i.e. those that end in other sentences.
// "Dangling Else" is solved by allowing exactly one "nested" compound sentence at the end,
// or one or more non-compound (simple) sentences.
// So "compound, compound, simple, simple" becomes "compound { compound { simple; simple } },
// not "compound { compound { simple }; simple }

conditionalSentence: AS condExpr COMMA compoundSentenceBody;

takeSentence: actor verb=(TAKE | TAKES) ((A | AN) name (LIKE example=expr)? | (THE? simpleVarName=simpleName)? example=expr)
              FROM source=expr COMMA? AND compoundSentenceBody;

compoundSentenceBody: compoundSentence | simpleSentences;

// Testing

expectSentence: WE EXPECT thatClauses;
thatClauses: thatClause (sep thatClause)*;
thatClause: THAT condExpr;

diagramSentence: IMG_START expr IMG_SEP fileName=FILE_NAME IMG_END;

// Matching

matchSentence: actor verb=(MATCH | MATCHES) (ON expr)? patternObjects;
patternObjects: patternObject (sep patternObject)*
              | COLON ((BULLET | NUMBERED) patternObject)+;

// --------------- Patterns & Constraints ---------------

patternObject: (SOME typeName | ALL typesName) name constraints?;
constraints: constraint (sep constraint)*;
constraint: linkConstraint
             | attributeEqualityConstraint
             | attributeConditionalConstraint
             // | attributePredicateConstraint
             | matchConstraint
             ;

linkConstraint: WITH SOME LINK TO name;
attributeEqualityConstraint: WITH (name expr | number name);
attributeConditionalConstraint: (WHERE SOME ATTRIBUTE | WHOSE name) condOp rhs=expr;
attributePredicateConstraint: (WHERE SOME ATTRIBUTE | WHOSE name) predOp;
matchConstraint: WHERE condExpr;

// --------------- Expressions ---------------

expr: access | collection;

// Primary
primary: number | booleanLiteral | stringLiteral | codeBlock | it | answer | nameAccess;
primaryExpr: primary;

number: DECIMAL | INTEGER;
booleanLiteral: TRUE | FALSE;
stringLiteral: STRING_LITERAL;
it: IT;
answer: THE? ANSWER;

simpleName: identifier;
name: identifier (identifier | INTEGER)*;

identifier: WORD
          // new keywords for pattern matching since v1.1
          | ATTRIBUTE
          | LINK
          | MATCH
          | MATCHES
          | SOME
          | WHERE
          | WHOSE
          // new keywords for placeholders since v1.4
          | EVERY
          | TYPE
          // new keywords for boolean literals since v1.7
          | TRUE
          | FALSE
          ;

nameAccess: THE? name;

// string: (WORD | NUMBER)+;

// Access

access: primary | attributeAccess | exampleAccess | filterExpr;
namedAccess: nameAccess | attributeAccess;
named: namedAccess | exampleAccess;

attributeAccess: THE? name OF access;
exampleAccess: primaryExpr FROM namedAccess;

filterExpr: ALL expr WHICH condExpr;

// Collections

sep: COMMA | AND | COMMA AND;

collection: list | range;

list: listElem (sep listElem)+;
listElem: access | range;

range: access TO access;

// Conditional

condExpr: andCondExpr;

andCondExpr: orCondExpr (AND orCondExpr)*;
orCondExpr: primaryCondExpr (OR primaryCondExpr)*;

primaryCondExpr : attrCheck | condOpExpr | predOpExpr;
attrCheck: access? (HAS | HAVE) namedExpr;

condOpExpr: lhs=access? condOp rhs=access;
condOp: eqOp | cmpOp | collOp | strOp;

eqOp: IS | ARE | (IS | ARE) NOT
    | (IS | ARE) THE SAME AS | (IS | ARE) NOT THE SAME AS;
cmpOp: (IS | ARE) LESS THAN | (IS | ARE) NOT LESS THAN | (IS | ARE) LESS EQUAL
     | (IS | ARE) GREATER THAN | (IS | ARE) GREATER EQUAL | (IS | ARE) NOT GREATER THAN;
collOp: CONTAIN | CONTAINS | (DO | DOES) NOT CONTAIN /* | (IS | ARE) IN | (IS | ARE) NOT IN */;
strOp: MATCH | MATCHES;

predOpExpr: lhs=access? predOp;

predOp: (IS | ARE) EMPTY | (IS | ARE) NOT EMPTY;




© 2015 - 2024 Weber Informatics LLC | Privacy Policy