Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ANTLR:如何用lexer解析匹配括号内的区域_Antlr_Matching_Lexer_Brackets - Fatal编程技术网

ANTLR:如何用lexer解析匹配括号内的区域

ANTLR:如何用lexer解析匹配括号内的区域,antlr,matching,lexer,brackets,Antlr,Matching,Lexer,Brackets,我想在我的lexer中解析如下内容: ( begin expression ) 其中表达式也用括号括起来。表达式中的内容并不重要,我只想将(begin和匹配的)之间的所有内容作为标记。例如: (begin (define x (+ 1 2))) 因此,令牌的文本应该是 (define x (+ 1 2))) 差不多 PROGRAM : LPAREN BEGIN .* RPAREN; (显然)不起作用,因为他一看到“)”,就认为规则结束了,但我需要匹配的括号 我该怎么做呢?在lexe

我想在我的lexer中解析如下内容:

( begin expression )
其中表达式也用括号括起来。表达式中的内容并不重要,我只想将
(begin
和匹配的
之间的所有内容作为标记。例如:

(begin 
    (define x (+ 1 2)))
因此,令牌的文本应该是

(define x (+ 1 2)))
差不多

PROGRAM : LPAREN BEGIN .* RPAREN;
(显然)不起作用,因为他一看到“)”,就认为规则结束了,但我需要匹配的括号


我该怎么做呢?

在lexer规则中,您可以递归调用规则。所以,这是解决这个问题的一种方法。另一种方法是跟踪开括号和闭括号的数量,只要计数器大于零,就允许循环

演示: T.g
语法T;
作语法分析
:BeginToken{System.out.println(“已解析::”+$BeginToken.text);}EOF
;
贝金托肯
@init{int open=1;}
:“(”开始“({open>0}?=>//只要open>0,就继续重复“(…)*”
(~('('|')//匹配除括号外的任何内容
|“({open++;}//在变量`open'中匹配一个“(”`
|“)”{open--;}//在变量“open”中匹配a')”`
)
)*
;
主类
import org.antlr.runtime.*;
公共班机{
公共静态void main(字符串[]args)引发异常{
字符串输入=“(开始(定义x(+-13)2))”;
TLexer lexer=新的TLexer(新的AntlStringStream(输入));
TParser parser=newtparser(newcommontokenstream(lexer));
parser.parse();
}
}
java-cp antlr-3.3-complete.jar org.antlr.Tool T.g
javac-cp antlr-3.3-complete.jar*.java
java-cp.:antlr-3.3-complete.jar Main
已解析::(开始(定义x(+-13)2)))
请注意,您需要注意源代码中可能包含括号的字符串文字:

BeginToken
@init{int open=1;}
:“(”开始“({open>0}?=>/。。。
( ~('(' | ')' | '"')     // ...
|“({open++;}//。。。
|“)”{open--;}/。。。
|“'”…//TODO:在此处定义字符串文字
)
)*
;
或可能包含括号的注释

谓词的建议使用一些特定于语言的代码(本例中为Java)。递归调用lexer规则的一个优点是,您的lexer中没有自定义代码:

BeginToken
:“(“空格?”开始“空格?嵌套的Parens空格”)”
;
片段嵌套排列
:“(-(“(”(“|”))|嵌套父母)*.”
;
片段空间
:(“|”\t”)+
;

如果您想识别(…)之间的所有内容,包括其他嵌套(…),那么您不能使用纯的、基于regexp的标准lexer(例如,我认为ANTLR),因为正则表达式不能计数-->无法确定括号何时平衡。您需要实现一个可以计数括号的词素识别器。@Ira,它是一个单词素。以大写字母开头的规则是ANTLR中的标记。我命名规则
Root
可能是一个错误的选择,这让您相信我推了这个问题我是语法分析器…啊哈。是的,正如你可能猜到的,我不是一个真正的ANTLR专家。所以…这就是我希望你能提供的答案。我再也不会怀疑你了!@Bart:我刚刚注意到我在这方面的另一个问题:lexer不再正确识别像
(bar…
)这样的语句,相反,他扔掉了(ba'并将
r
作为标识符返回,尽管我想使用LPAREN标识符。我如何解决这个问题?我是否应该就此提出另一个问题并再次发布语法?是的,这是lexer不喜欢的。如果输入“看起来”像
(b.
,lexer在备份到
LPAREN标识符
而不是
BeginToken
时遇到问题。这真的是您想要在lexer中处理的事情吗?在解析器中匹配
BeginToken
比在lexer中匹配
BeginToken
更容易。是的,创建新问题可能更容易(以防您真的想在lexer中执行此操作)。