2015-08-13 79 views
0

我的語言具有可參數小於或帶有參數的命令,並在「如果」的文章:Antlr4詞法採取錯誤的規則

cmd1   // parameter-less command 
cmd2 a word // with parameter: "a word" - it starts with first non-WS char 
if cmd3   // if, not a command, followed by parameter-less command 
cmd4 if text // command with parameter: "if text" 

「如果」是公認if只有當它的第一個非WS字符串(讓我們暫時忽略註釋...)

這些是我的語法規則: 語法TestFlow;作爲if其次if cmd3,而不是由cmd3因爲我需要:

// Parser Rules: 
root: (lineComment | ifStat | cmd)* EOF; 

lineComment : LC; 
ifStat : IF; 
cmd : CMD; 

// Lexer Rules: 
LC : '//' ~([\n\r\u2028\u2029])* -> channel(HIDDEN); // line comment 

IF : 'if'; 

CMD : [-_a-zA-Z0-9]+ GAP LINE 
    | [-_a-zA-Z0-9]+ 
    ; 

fragment GAP : [ \t]+; 
fragment LINE : ~([\n\r\u2028\u2029])*; 

但我的詞法分析器識別3號線爲CMD

我的錯誤是什麼?如何解決它?

回答

0

您的示例中似乎沒有解析器規則來定義語法。意思是沒有規則表示尋找'如果'和一個命令。

什麼是你的話發生的事情:

但我的詞法分析器識別3號線爲CMD:如果CMD3,而不是好像後面,因爲我需要

中的第一個替代CMD3詞法分析器規則CMD查找一個或多個字符(「if」),後跟一個空格「',後跟一個LINE(cmd3)。 因此,使用輸入「if cmd3」它匹配整條線,這正是您告訴它做的!

我可以從個人的經驗告訴你,因爲即便是一個簡單的語言,你會被退後一步學習很多和非常迅速,回顧一些例子語法,這是,如果我是你,我會做什麼現在要避免受挫。我高度推薦從www.pragprog.com antlr4參考書以及antlr網站。

更新 我覺得這是你可能會感興趣的東西:

grammar myGrammar; 

root  : statement NEWLINE 
      | comment NEWLINE 
      ; 

statement : ifStat (LC)? 
      | cmdStat (LC)? 
      ; 

ifStat  : IF cmdStat; 
cmdStat  : cmd (args)*; 

cmd  : CMD; 

args  : LINE; 
CMD  : [-_a-zA-Z0-9]+ GAP LINE 
      | [-_a-zA-Z0-9]+ 
     ; 

fragment GAP : [ \t]+; 
fragment LINE : ~([\n\r\u2028\u2029])*; 
NEWLINE  : ('\r')?'\n'; 

同樣,我必須說,如果你讀的書(我做了),這可能會給你預期的響應從你的解析器(而不是詞法分析器)。 ifStat是可選的(根據您的測試用例,可能不存在),總是會有一個cmd,並且可能有或者可能沒有後面的行註釋。嘗試一下,看看它是否有幫助。祝你好運!

+0

我最初排除了解析器規則,因爲在我看來,這是一個詞法分析器問題。無論如何,如果有幫助,我更新了我的問題以包含解析器規則。第二件事:'IF'規則出現在'CMD'之前,所以我認爲它優先。 – Tar

+0

如果你提到的是「The Definitive ANTLR4 Reference」這本書,那麼我就是這樣寫的,但這不是一本很好的「入門」教程。 – Tar

+0

'root:((ifStat)?cmd(lineComment)?)* EOF;'也不起作用。問題是'如果cmd3'出現在'commonTokenStream.getTokens()'所得的單個令牌中。所以如果它是一個單一的標記,這就是解析器從詞法分析器得到的東西,它不能將它們分開。這就是爲什麼我認爲這是一個詞法分析器問題,而不是解析器 – Tar