2011-06-26 49 views
1

一些語法問題,我一直在做的是包括從文本文件中讀取和excersise:在ANTLR

  • 更換連續的空格/製表符,只有一個空間
  • 只更換連續換行符一個
  • 可使所有文字大寫。

當我執行它,它不寫什麼到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); 
+0

沒打過多少與V3,但是我發現在一個教程此評論:「一個詞法規則可以參考其他詞法規則,他們常常引用‘片段’詞法規則,這不會導致創建令牌,並且是。只是爲了簡化其他詞法分析規則的定義。「也許從定義中刪除'片段'將有所幫助?此外,而不是'Spaces {w.Write($ Spaces.text); }',嘗試'sp = Spaces {w.Write($ sp.text); }'。 –

+0

@OwenS。謝謝。這是問題所在。另外,你能解釋爲什麼你建議'sp = Spaces ...'而不是直接做? –

+1

之間存在'空間{w.Write($ Spaces.text)沒有差異; }'和'sp = Spaces {w.Write($ sp.text);} }'。 ';令牌令牌:'FOO:當使用兩個相同的記號或製作後者被使用。引用它們中的一個,那麼, 「標籤」 被分配給它們:'FOO爲:a =令牌B =令牌{... $ a.text ... $ b.text ...};' –

回答

2

片段規則只能從其他詞法規則中,從語法規則,如你正在努力。只需從3個詞法分析器規則中刪除fragment關鍵字即可。

此外,片段:

$text = " "; 

轉換爲下面的(僞代碼):

getText() = " " 

這是無效的(至少使用Java時,目標是無效的)。您可能想嘗試:

Spaces  : (' '|'\t')+ { SetText(" "); }; 

改爲。但是CSharp3目標可能只是接受它。

+0

這就是訣竅:)而關於「SetText(...)',感謝您的建議。很高興知道這一點,儘管在CSharp3中它似乎是有效的;) –

+0

知道* fragment *規則的含義是什麼時,這是完全有意義的;)如果分片規則不會成爲標記,分析器如何應該與它一起工作? :) –

+0

@Oscar,很高興知道CSharp3接受它。 Java目標_does_接受'$ type = SOME_TYPE',所以我一直覺得奇怪爲什麼'$ text =「some text」'不起作用。當然你也歡迎你! –