如何创建一个解析器来标记从文件中获取的单词列表?

时间:2010-06-25 20:30:15

标签: parsing antlr yacc lex ragel

我正在尝试为我的编译器类做一个语法文本校正器。这个想法是:我有一些规则,这是语言所固有的(在我的例子中,葡萄牙语),如“一个有效的短语是主要的动词目标”,如“Ruby很棒”。

好的,首先我必须将输入标记为“Ruby很棒”。所以我有一个文本文件“动词”,有很多动词,一个接一个。然后我有一个文本“形容词”,一个“代词”等等。

我正在尝试使用Ragel来创建一个解析器,但我不知道我该怎么做:

%%{
  machine test;
  subject = <open-the-subjects-file-and-accept-each-one-of-them>;
  verb = <open-the-verbs-file-and-accept-each-one-of-them>;
  adjective = <open-the-adjective-file-and-accept-each-one-of-them>;
  main = subject verb adjective @ { print "Valid phrase!" } ;
}%%

我看了ANTLR,Lex / Yacc,Ragel等。但找不到一个似乎可以解决这个问题。我能想到的唯一方法是预处理Ragel的输入文件,以便我的程序读取文件并将其内容写入正确的位置。但我也不喜欢这个解决方案。

有谁知道我怎么能这样做?如果没有Ragel没有问题,我只是想解决这个问题。我想使用Ruby或Python,但这也不是必需的。

感谢。

2 个答案:

答案 0 :(得分:2)

如果要在编译时读取文件,请将它们格式化为:

subject = \
ruby|\
python|\
c++

然后使用ragel的'include'或'import'语句(我忘了哪个......必须检查手册)来导入它。


如果你想在运行时检查主题列表,也许只需让ragel读3个单词,然后让每个单词都有一个动作。该操作可以读取文件并在运行时查找该单词是否正常。

该操作读取文本文件并比较单词的内容。

%%{
machine test

action startWord {
    lastWordStart = p;
}
action checkSubject {
   word = input[lastWordStart:p+1]  
   for possible in open('subjects.txt'):
       if possible == word:
           fgoto verb
   # If we get here do whatever ragel does to go to an error or just raise a python exception 
   raise Exception("Invalid subject '%s'" % word)
}
action checkVerb { .. exercise for reader .. ;) }
action checkAdjective { .. put adjective checking code here .. }

subject = ws*.(alnum*)>startWord%checkSubject
verb := : ws*.(alnum*)>startWord%checkVerb
adjective := ws*.)alnum*)>startWord%checkAdjective
main := subject;
}%%

答案 1 :(得分:0)

使用野牛,我会手动编写词法分析器,查找预定义词典中的单词。