我需要“{”在一条线上单身。因此,我必须使用识别它的令牌。这是正确的例子:
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”。
答案 0 :(得分:0)
基本问题是您在没有任何解释的情况下打印输入。换句话说,正如你所发现的那样,所发生的是什么。
为了更容易阅读 - 并且为了不在某些方面滥用词法分析器强制它完成整个任务 - 我建议将你的print语句向下移动到解析器中(例如, 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个换行符。
如果你可以用大括号开始一个文件,而不需要一个单词,那么它输出并清空行,大括号和换行符。我不知道这是不是你想要的,能够用空行开始输出,所以你需要使用输出代码来获得你想要的确切格式,另外,你可以看到你在那里有一些非常好的重复代码可以被提取到一个函数中,所以我把它留给读者练习。
无论如何,这个答案的基本前提是---我相信这确实是一个适合各个时代的格言,适用于生活的各个方面,而不仅仅是编码 - “除非你改变你所采取的在输出之前,它就是你所接受的!“
答案 1 :(得分:0)
我做的不同:
TOKEN: { < openKey: "\n" (" " | "\t")* "{" (" " | "\t")* ("\r" | "\n") >{System.out.print("{\r\n");}}
SKIP: { " " | "\r" | "\t" | "\n" }
回车有一些问题,但这种方式效果很好。