使用SLR / LR / LALR解析器解析引号

时间:2015-10-12 18:02:01

标签: string parsing compiler-construction

我正在尝试解析由空格分隔的列表,但可能包含我必须将其视为文字的引号。所以我尝试编写一个语法并使用我最喜欢的解析算法解析它,但我似乎无法正确理解语法。

使得它变得棘手的特殊之处在于我必须处理" "" "情况,该情况应该被解释为带有两个引号的一个字符串,而"" ""应该是两个空字符串。

为了解决问题,我必须处理单引号' '* *括号内的评论。例如:' * ' " * ' "是允许的,应该解析为** '

这是完全不可能还是有语法可以做到?

我设法提出的最佳尝试(_表示空间):

start -> argv $
argv -> argv _ term | term
term -> "" | '' | ** | "dqexpr" | 'sqexpr' | *comment* | expr
expr -> string without ", ', *, or _
dqexpr -> string without "
sqexpr -> string without '
comment -> string without *

但我无法使用LR(1)/ SLR(1)解析器在" "" "上进行此工作。

我尝试的语法,对于没有注释且只有一种引用类型的简单情况:

START -> ARGV $
ARGV -> ARGV _ TERM
ARGV -> TERM
TERM -> q STRING q
TERM -> FREE
STRING -> STRING CHAR
CHAR -> ''
CHAR -> q
CHAR -> c
FREE -> FREE c
FREE -> c

在这里,''是epsilon; q代表引用,_代表空格,c代表任何其他字符。可以使用http://jsmachines.sourceforge.net/machines/slr.html

上的在线工具尝试语法

2 个答案:

答案 0 :(得分:1)

您尝试的语法中的TERM -> q STRING q非终端无用(也就是说,它无法派生任何终端字符串),因为它没有非递归生成。所以解析器生成器应该丢弃它,以及CHAR -> ''生成。 (理想情况下,会生成相应的错误消息。)如果已修复,生产STRING会产生歧义,因为CHAR可以是任意数量的CHAR -> '',你无法分辨空字符串中有多少个epsilons。理想情况下,解析器生成器将提供有意义的错误消息,但可以看出,并非所有都这样做。

这可以通过简单地将STRING -> ''更改为STRING来解决,这也将解决由连接两个epsilons的模糊性所产生的冲突。剩下的就是允许引用的q包含dqexpr -> string without ",这与伪代码(“" "" "”)中的描述相矛盾。

如果意图是允许一个术语是引用字符串的串联,以便QTERMS -> QTERM QTERMS -> QTERMS QTERM QTERM -> q STRING q 有效(不进入其语义),可以通过添加另一个非终端迭代来完成:

TERM -> q STRING q

并将TERM -> QTERM更改为" "" "

我的怀疑是,欲望是一种简化的shell文字处理形式,其中“单词”可以是任意数量的术语的连接,因此" "' '不仅是一个合法的单词,而且是"x"foo'y'"'"'"'。这允许在同一个单词中包括单引号和双引号:START -> ARGV $ ARGV -> WORD ARGV -> ARGV WHITES WORD WHITES -> WHITE WHITES -> WHITES WHITE WHITE -> _ WHITE -> star CSTRING star WORD -> TERM WORD -> WORD TERM TERM -> c TERM -> squote SQSTRING squote TERM -> dquote DQSTRING dquote SQSTRING -> '' SQSTRING -> SQSTRING c SQSTRING -> SQSTRING _ SQSTRING -> SQSTRING star SQSTRING -> SQSTRING dquote DQSTRING -> '' DQSTRING -> DQSTRING c DQSTRING -> DQSTRING _ DQSTRING -> DQSTRING star DQSTRING -> DQSTRING squote CSTRING -> '' CSTRING -> CSTRING c CSTRING -> CSTRING _ CSTRING -> CSTRING squote CSTRING -> CSTRING squote 。如果我们也假设评论等同于空格,我们最终会得到以下语法:

public static class MainActivity extends Activity
        implements MainFragment.onFragmentInteraction{
    ...

    public void onFragmentInteraction() {
        // Do something 
        callFunction();
    }
}

您使用的SLR tool使用上述语法成功生成解析器。

答案 1 :(得分:0)

语法实际上应该与匹配的括号相同,所以你应该能够在解析数学表达式时找到很多例子。

我不确定你的示例语法试图完成什么,但在你的// Forward declare MyStruct struct MyStruct; class AnotherClass { AnotherClass(MyStruct & myStruct) : m_myStruct(myStruct) { } MyStruct & m_myStruct; }; 规则中包含“”,“和”**对我来说似乎很奇怪。尝试将其更改为:

term