我正在尝试为众所周知的MUD脚本语言创建语法。我正在努力解决一些问题,主要涉及空白,重用关键字以及使用注释符号的命令。如果这很重要,我的目标很快。任何帮助将不胜感激!
我正在使用此处找到的Swift-Target:https://github.com/janyou/ANTLR-Swift-Target
具体问题:
洞察要求:
有效命令的一些示例:
# a comment
put hello world
# - this should echo "hello world"
echo hello world
label:
goto label
put #echo hello world
#keywords are case insensitive
GOTO label
GoTo label
Goto label
# this is treated as a label vs. a command, even though it uses a keyword
goto:
# commands that start with comment symbol - '#echo' is a special command
# these special commands can only be used with 'put' or 'send' keywords
put #echo one %localvar
# variables <keyword> <variable name> <value>
var var_name myvar value can be multiple words
var var-name alksdf
var var.name alksdf
# variables can be used as label names
$globalvar:
# local and global variables can be combined to create one "merged" variable
%localvar$globalvar:
put leading text $globalvar%localvar some other text
put get %1 from my backpack
put get $0 from my backpack
# inline regex
put #parse ^(a regex)
put this is some text;this is more text sent separately
matchre label ^(a regex)
matchwait 4
pause 1.5
action var person $1 when ^(\S+) gives you a gentle poke in the ribs
action goto tend when eval $bleeding = 1
action (info) var circle $1;put #var circle $1 when Circle:\s+(\d+)$
# single line if blocks
if %somevar then goto end
if (%somevar == 1) { goto end }
# multi-line if block with brackets
if 1 > 2 then {
# more commands
send #echo
# infinite nested blocks
if ("%one" == "$three" || 5.6 < 11.12)
{
# more commands
put nested commands
}
}
# function names - function names can be used with the 'eval' keyword or in if expressions
# example here is the 'countsplit()' function with two parameters
var weapons spear|"imperial hammer"|sword|offhand lob dagger|lob "throwing hammer"
eval weapon_count countsplit(%weapons, "|")
echo %weapon_count
if matchre("%dir", "^(search|swim|climb) ") || %somevar then
{
var type $1
echo matched %type
}
到目前为止,这是我简单的语法:
grammar Gsl;
document :
line+ EOF
;
line :
BOL WS* key WS promptkey? value eol
;
value
: any_except_newline*
;
key
: ECHO
| PUT
;
prompt
: '#' promptkey
;
promptkey
: 'echo'
| 'send'
;
any_except_newline
: COLON
| ECHO
| PUT
| WORD
| WS
| ANYCHAR
;
eol : NEWLINE | EOF ;
ECHO : E C H O;
PUT : P U T;
BOL : [\r\n\f]+ ;
LC : BOL '#' ~[\r\n]* -> channel(HIDDEN) ;
NEWLINE : [\r\n];
COLON : ':';
WORD : ('a'..'z' | 'A'..'Z')+;
WS : [ \t] ;
ANYCHAR : .;
fragment A:('a'|'A');
fragment B:('b'|'B');
fragment C:('c'|'C');
fragment D:('d'|'D');
fragment E:('e'|'E');
fragment F:('f'|'F');
fragment G:('g'|'G');
fragment H:('h'|'H');
fragment I:('i'|'I');
fragment J:('j'|'J');
fragment K:('k'|'K');
fragment L:('l'|'L');
fragment M:('m'|'M');
fragment N:('n'|'N');
fragment O:('o'|'O');
fragment P:('p'|'P');
fragment Q:('q'|'Q');
fragment R:('r'|'R');
fragment S:('s'|'S');
fragment T:('t'|'T');
fragment U:('u'|'U');
fragment V:('v'|'V');
fragment W:('w'|'W');
fragment X:('x'|'X');
fragment Y:('y'|'Y');
fragment Z:('z'|'Z');