C# ANTLR中的一些语法问题
我一直在做一个练习,内容是从文本文件中读取,然后:C# ANTLR中的一些语法问题,c#,antlr,C#,Antlr,我一直在做一个练习,内容是从文本文件中读取,然后: 仅用一个空格替换连续的空格/制表符 仅用一个替换连续的换行符 使所有文本大写 当我执行它时,它不会向output.txt文件写入任何内容 我试图找出这个问题已有一段时间了,但没有成功。这是我的密码: grammar Ejerc1; options { language = CSharp3; } @header { using System.IO; using System; } fragment Spaces : ('
- 仅用一个空格替换连续的空格/制表符
- 仅用一个替换连续的换行符
- 使所有文本大写
output.txt
文件写入任何内容
我试图找出这个问题已有一段时间了,但没有成功。这是我的密码:
grammar Ejerc1;
options
{
language = CSharp3;
}
@header
{
using System.IO;
using System;
}
fragment Spaces : (' '|'\t')+ { $text = " "; };
fragment Any : (~(' '|'\t'|'\n'|'\r'))+ { $text = $text.ToUpper(); };
fragment NewLines : ('\r'|'\n')+ { $text = "\r\n"; };
/* Parser */
public file[string filePath]
@init {
if (File.Exists($filePath)) {
File.Delete($filePath);
}
StreamWriter w = new StreamWriter($filePath);
}
@after {
w.Close();
}
:
(
Spaces { w.Write($Spaces.text); }
|NewLines { w.Write($NewLines.text); }
|Any { w.Write($Any.text); }
)*
EOF;
下面是Main
方法中的代码:
string inputPath = "text.txt";
string outputPath = "output.txt";
var input = new ANTLRFileStream(inputPath);
var lexer = new Ejerc1Lexer(input);
var tokens = new CommonTokenStream(lexer);
var parser = new Ejerc1Parser(tokens);
parser.file(outputPath);
片段规则只能从其他lexer规则中使用,不能从解析器规则中使用,正如您正在尝试的那样。只需从3个lexer规则中删除
片段
关键字即可
此外,代码段:
$text = " ";
转换为以下内容(伪代码):
这是无效的(至少在使用Java目标时是无效的)。您可能要尝试:
Spaces : (' '|'\t')+ { SetText(" "); };
相反。但是CSharp3目标可能会接受它。没有在v3上玩太多,但我在一个教程中发现了这样的评论:“lexer规则可以引用其他lexer规则。它们通常引用‘fragment’lexer规则。这些规则不会导致创建标记,并且只用于简化其他lexer规则的定义。”也许从定义中删除“片段”会有所帮助?另外,不要使用
Spaces{w.Write($Spaces.text);}
,而是尝试sp=Spaces{w.Write($sp.text);}
@OwenS。谢谢这就是问题所在。另外,你能解释一下为什么你建议做sp=Spaces…
而不是直接做吗?在Spaces{w.Write($Spaces.text);}
和sp=Spaces{w.Write($sp.text);}
之间没有区别。后者在使用两个相同的令牌或产品时使用:foo:Token-Token代码>。若要引用其中一个,则会为它们分配一个“标签”:foo:a=Token b=Token{…$a.text…$b.text…}代码>@BartKiers明白了。再次感谢:)成功了:)关于做SetText(…)
,谢谢你的建议。很高兴知道,尽管在CSharp3中它似乎是有效的;)在了解片段规则的含义后,这完全有道理;)如果片段规则不会成为令牌,那么解析器应该如何使用它呢?:)@奥斯卡,很高兴知道CSharp3接受了。Java目标确实接受$type=SOME_type
,所以我总是觉得奇怪为什么$text=“SOME text”
不起作用。当然不客气!
Spaces : (' '|'\t')+ { SetText(" "); };