如何在LBNF语法中用空行替代#分隔函数声明?
问题
我有如下简单的LBNF语法片段(仅为片段,无需编译):
ProgDef . Program ::= [FunDec] ; TypeBit . Type ::= "Bit" ; position token Var ((lower | '_') (letter | digit | '_' | '\'')*) ; FunArg . Arg ::= Var ; separator Arg " " ; FunDef . Function ::= Var [Arg] "=" Term ; FunDecl . FunDec ::= Var "::" Type Function ; separator FunDec "#" ;
当我解析以下源码时:
main :: Bit main = fun1 fun2 # main :: Bit main = fun1 fun2
语法解析工作正常,但我希望移除分隔函数声明的#字符,改用空行作为分隔符,请问该如何实现?
解决方案
要实现用空行分隔FunDec,你需要做以下两步修改:
定义空白行的Token
空行本质是包含至少一个换行的空白序列,先在语法里添加这个Token的定义:token BlankLine (('\n' | '\r\n') ((' ' | '\t')* ('\n' | '\r\n'))+) ;这个规则匹配一个或多个连续的空行,空行内允许包含空格或制表符。
替换分隔符规则
把原来指定#为分隔符的规则,替换成用刚定义的BlankLine作为分隔符:FunDecl . FunDec ::= Var "::" Type Function ; separator FunDec BlankLine ;
如果你的LBNF工具默认忽略普通空白(比如单个换行、空格),上面的规则就能精准识别空行作为分隔符,单个换行不会被误判成分隔符。
修改后的关键语法片段如下:
ProgDef . Program ::= [FunDec] ; TypeBit . Type ::= "Bit" ; position token Var ((lower | '_') (letter | digit | '_' | '\'')*) ; token BlankLine (('\n' | '\r\n') ((' ' | '\t')* ('\n' | '\r\n'))+) ; FunArg . Arg ::= Var ; separator Arg " " ; FunDef . Function ::= Var [Arg] "=" Term ; FunDecl . FunDec ::= Var "::" Type Function ; separator FunDec BlankLine ;
此时测试源码去掉#、换成空行即可正常解析:
main :: Bit main = fun1 fun2 main :: Bit main = fun1 fun2
内容的提问来源于stack exchange,提问作者Radu M.
相关产品推荐
相关产品推荐

