Files
inkblot/InkBlot/InkBlotAntlrGrammar.g4

153 lines
3.4 KiB
ANTLR

grammar InkBlotAntlrGrammar;
import InkBlotAntlrLexer;
/*
* STORY
*/
story: topLevelStatements ;
/*
* STATEMENTS FOR THE VARIOUS LEVELS
*/
topLevelStatements:
topLevelStatement+
;
topLevelStatement:
contentText
| multiDivert
;
knotLevelStatements:
(contentText
| multiDivert
)+
;
stitchLevelStatements:
(contentText
| multiDivert
)+
;
innerBlockLevelStatements:
(contentText
| multiDivert
)+
;
/*
* STATEMENTS
*/
contentText: CONTENT_TEXT_NO_ESCAPE_SIMPLE ;
mixedTextAndLogic:
// TODO: ~ is not allowed as first symbol of this (see InkParser_Content => MixedTextAndLog), let's implement it in the C# side?
// like in innerInlineSequenceObjects, a bit of a chaos to avoid having completely empty entries
contentText? (inlineLogicOrGlueOrTagStart? contentText | inlineLogicOrGlueOrTagStart contentText?)+
// TODO: this is valid only when not parsing a choice, see above for the code where this logic is implemented
multiDivert
// TODO: management of tag ftw O_O
;
inlineLogicOrGlueOrTagStart:
inlineLogic
// TODO: glue, tag start
;
inlineLogic:
INLINE_LOGIC_START
WS?
innerLogic
// TODO: += and -= are disabled here (don't know why)
WS?
INLINE_LOGIC_END
// TODO: tags ftw
;
innerLogic:
WS?
sequenceTypeAnnotation innerSequenceObjects
// TODO: the rest of InkParser_Logic => InnerLogic
;
multiDivert:
WS?
(
THREAD_ARROW divertIdentifierWithArguments
// here be dragons: trying to express the various "Possible patterns" of InkParser_Divert => MultiDivert
| (DIVERT_ARROW divertIdentifierWithArguments)+ TUNNEL_ARROW divertIdentifierWithArguments
| (DIVERT_ARROW divertIdentifierWithArguments)+ TUNNEL_ARROW
| (DIVERT_ARROW divertIdentifierWithArguments)+ DIVERT_ARROW
| TUNNEL_ARROW
| DIVERT_ARROW // TODO: this is only valid in default choices ( https://github.com/inkle/ink/blob/master/Documentation/WritingWithInk.md#fallback-choices )
)
;
divertIdentifierWithArguments:
WS? identifier WS? ('.' WS? identifier WS? )*
WS?
(
'('
expression (',' expression)*
')'
)?
WS?
;
identifier:
// TODO: reject numbers-only identifier - see InkParser_Logic => Identifier
IDENTIFIER
;
expression:
// TODO: temporary stuff here
IDENTIFIER
;
// all possible symbols or word(s) for sequencing
sequenceTypeAnnotation:
op=SEQUENCE_TYPE_SYMBOL_ANNOTATION
| ONCE
| CYCLE
| SHUFFLE
| STOPPING
| SHUFFLE_ONCE
| SHUFFLE_STOPPING
;
/* a list of sequence objects, either compressed in a single line (e.g.: {a|b|c}) or expanded in multiple lines (e.g.:
{\n- a\n- b\n- c}
*/
innerSequenceObjects:
NL innerMultilineSequenceObjects
| innerInlineSequenceObjects
;
innerMultilineSequenceObjects:
singleMultilineSequenceElement+
;
singleMultilineSequenceElement:
WS?
/* TODO: how to express this? and why is it here? InkParser_Sequences => SingleMultilineSequenceElement
if (ParseString ("->") != null)
return null;
*/
'-'
WS?
(
innerBlockLevelStatements
| MULTILINE_WS
)
;
innerInlineSequenceObjects:
// it's a bit chaotic, in order to allow for empty mixedTextAndLogic, but always require at least one entry
(mixedTextAndLogic ('|' mixedTextAndLogic?)*)
| ('|' mixedTextAndLogic?)+
;