172 lines
4.0 KiB
ANTLR
172 lines
4.0 KiB
ANTLR
grammar InkBlotAntlrGrammar;
|
|
|
|
import InkBlotAntlrLexer;
|
|
|
|
/*
|
|
* STORY
|
|
*/
|
|
|
|
story: topLevelStatements ;
|
|
|
|
/*
|
|
* STATEMENTS FOR THE VARIOUS LEVELS
|
|
*/
|
|
|
|
topLevelStatements:
|
|
topLevelStatement+
|
|
;
|
|
|
|
topLevelStatement:
|
|
multiDivert
|
|
| contentText
|
|
;
|
|
|
|
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, maybe because they're statements?)
|
|
WS?
|
|
INLINE_LOGIC_END
|
|
// TODO: tags ftw
|
|
;
|
|
|
|
innerLogic:
|
|
WS?
|
|
sequenceTypeAnnotation innerSequenceObjects
|
|
// TODO: the rest of InkParser_Logic => InnerLogic
|
|
;
|
|
|
|
multiDivert:
|
|
WS?
|
|
multiDivert_withoutWS
|
|
;
|
|
|
|
multiDivert_withoutWS:
|
|
THREAD_ARROW divertIdentifierWithArguments # MultiDivertThread
|
|
// here be dragons: trying to express the various "Possible patterns" of InkParser_Divert => MultiDivert
|
|
// syntax in the original ink parser is overly concessive: https://discord.com/channels/329929050866843648/329929390358265857/1342130940981284945
|
|
| (DIVERT_ARROW divertIdentifierWithArguments)* multiDivertArrows_tail # MultiDivertArrows
|
|
// TODO: a single DIVERT_ARROW above is only valid in default choices ( https://github.com/inkle/ink/blob/master/Documentation/WritingWithInk.md#fallback-choices )
|
|
// TODO: tags ftw
|
|
;
|
|
|
|
multiDivertArrows_tail:
|
|
DIVERT_ARROW # MultiDivertArrows_tailDefaultChoice
|
|
| DIVERT_ARROW divertIdentifierWithArguments # MultiDivertArrows_tailDivert
|
|
| TUNNEL_ARROW divertIdentifierWithArguments # MultiDivertArrows_tailTunnelWithReplacement
|
|
| TUNNEL_ARROW # MultiDivertArrows_tailTunnel
|
|
;
|
|
|
|
divertIdentifierWithArguments:
|
|
WS?
|
|
divertIdentifierWithArguments_name
|
|
WS?
|
|
(
|
|
'('
|
|
expression (',' WS? expression)*
|
|
')'
|
|
)?
|
|
WS?
|
|
;
|
|
|
|
divertIdentifierWithArguments_name:
|
|
WS? identifier WS? ('.' WS? identifier WS? )*
|
|
;
|
|
|
|
divertIdentifierWithArguments_arguments:
|
|
'('
|
|
expression (',' WS? expression)*
|
|
')'
|
|
;
|
|
|
|
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?)+
|
|
; |