使用ANTLR手动发出令牌

时间:2010-01-12 14:24:12

标签: parsing compiler-construction antlr

我在ANTLR中手动发出带有词法分析器规则的令牌时遇到了一些麻烦。我知道需要使用emit()函数,但似乎缺乏关于此的文档。有没有人有一个如何做到这一点的好例子?

ANTLR书提供了一个很好的例子,说明了如何解析Python的嵌套。例如,如果您看到一定数量的空白大于前一行的空格,则发出一个INDENT令牌但如果它更少,则发出一个DEDENT令牌。不幸的是,这本书掩盖了所需的实际语法。

编辑:这是我正在尝试解析的一个例子。这是Markdown的嵌套块引用:

before blockquote

> text1
>
> > text2
>
> text3

outside blockquote

现在,到目前为止,我的方法基本上是计算>每行符号。例如,上面似乎应该发出(大致......)PARAGRAPH_START,CDATA,PARAGRAPH_END,BQUOTE_START,CDATA,BQUOTE_START,CDATA,BQUOTE_END,CDATA,BQUOTE_END,PARAGRAPH_START,CDATA,PARAGRAPH_END。这里的难点是最终的BQUOTE_END,我认为应该是一旦找到非blockquote元素时发出的虚构标记(并且嵌套级别为> = 1)

2 个答案:

答案 0 :(得分:2)

如果你想要发出的令牌没有被词法分析器规则定义,那么你需要像这样添加一个令牌部分:

tokens
{
    MYFAKETOKEN
}

在词法分析器中,您仍然需要一条规则来告诉词法分析器何时生成此令牌。一个常见的例子是确定某些东西是整数还是范围或实际值。

NUMBERS_OR_RANGE
: INT 
        ( { LA(1) == '.' && LA(2) == '.' }? { _ttype = INT; }
    | { LA(1) == '.' || LA(1) == 'e' || LA(1) == 'E' }? { _ttype = REAL; }
    )
| PERIOD 
    ( PERIOD { _ttype = RANGE; }
    INT (( 'e' | 'E' ) ( '-' | '+' )? INT )? { _ttype = REAL; }
)
;

在这里你可以看到我们匹配一个INT然后匹配前瞻,如果我们找到一个双周期,那么我们知道INT实际上是一个int而不是一个真实的。在这种情况下,我们将变量_ttype设置为INT。如果我们找到PERIOD然后是'e',我们知道它是真实的。

我们知道如果下一个字符是一个句点,那么我们知道如果我们知道如果下一个字符是一个句号,那么我们就有了一个范围,否则我们就会得到一个真实的。

如果合适,我们可以使用上面定义的MYFAKETOKEN类型分配给_ttype。

答案 1 :(得分:0)

好的,我做了一些研究,发现了这个:http://www.cforcoding.com/2010/01/markdown-and-introduction-to-parsing.html

我不认为ANTLR真的是为这类任务而设置的,并试图向后弯腰去做这件事并不值得。