具有重要空白的Antlr语法,重用注释符号

时间:2016-06-11 22:27:56

标签: swift antlr4

我正在尝试为众所周知的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');

0 个答案:

没有答案