0

我需要“{”将单行。因此,我必须使用识别它的令牌。这是正确的例子:

program
{

或者

program



{

这是不正确的例子:

program { 

或者

program 
{ sentence;

然后我有一个像这样的令牌:

TOKEN: { < openKey: "{" >   {System.out.print(image +"\n");}}
SKIP: { < ( " " | "\r" | "\t" | "\n" )+ > }

但我想不出如何使符号“{”恰好在一个或多个“\n”之间。在认识到它之后,我必须准确地写:

program
{

如果我尝试:

TOKEN: { < openKey: ( " " | "\r" | "\t" | "\n" )+ "{" ( " " | "\r" | "\t" | "\n" )+ >   {System.out.print(image +"\n");}}

这会运行,但它会写很多“\n”,就像输入中的一样。

4

2 回答 2

0

基本问题是您在没有任何解释的情况下打印输入。换句话说,正如你所发现的,进去的就是出来的。

为了使它更容易阅读——并且为了避免在某些方面通过强制它完成整个任务来滥用词法分析器——我建议将你的打印语句向下移动到解析器中(例如,在 Start( ) 功能)。(实际上,我倾向于将所有输出完全移出解析器,除非我正在做一些我永远不会重用的非常小的事情,但这是另一个问题。)

接下来,为了解决实际问题,您需要做一些解释,从一堆换行符变成一个。最简单的方法是基本的 replaceAll。这是我的 Start() 函数,其中 openKey 的定义与您所做的一样,而 WORD 只是字母的串联。

void Start() : 
{
  Token t;
}
{
    ( 
      t = <WORD>
      {System.out.print((t.image).replaceAll("(\n)+","\n"));}
    )*
    (
            t = <openKey>
            {System.out.print((t.image).replaceAll("(\n)+","\n"));}
            ( 
              t = <WORD>
              {System.out.print((t.image).replaceAll("(\n)+","\n"));}
            )*
    )*
    <EOF>

}

所以基本上,这需要零个或多个单词,后跟包含 1 个或多个换行符的单元,后跟左花括号,后跟 1 个或多个换行符,后跟零个或多个单词,并输出单词,大括号,每个 1 个或多个换行符集只有 1 个换行符。

如果您可以使用花括号开始文件,而不需要单词,那么它会输出空行、花括号和换行符。我不知道这是否是你想要的,能够以空行开始输出,所以你需要使用输出代码来获得你想要的确切格式,另外,你可以看到你那里有一些非常好的重复代码,可以提取到一个函数中,所以我把它留给读者练习。

无论如何,这个答案的基本前提是——而且我相信这确实是一个古老的格言,适用于生活的各个领域,而不仅仅是编码——“除非你在输出之前改变你所接受的它,这将是你所接受的!”

于 2012-07-04T09:37:46.783 回答
0

我做了不同的事情:

TOKEN: { < openKey: "\n" (" " | "\t")* "{" (" " | "\t")* ("\r" | "\n") >{System.out.print("{\r\n");}}   
SKIP: { " " | "\r" | "\t" | "\n" }

回车有一些问题,但这种方式效果很好。

于 2012-07-24T14:19:42.240 回答