我想检查字符串,如果它与使用YACC和LEX的语法String sql = "UPDATE table1 SET col1=?, col2=? WHERE col1=? and col2=?";
java.sql.PreparedStatement stmt = conn.prepareStatement(sql); //conn is sql connection to DB
if (time1 != null) stmt.setTimestamp(1, time1); else stmt.setNull(1, java.sql.Types.TIMESTAMP);
if (time2 != null) stmt.setTimestamp(2, time2); else stmt.setNull(2, java.sql.Types.TIMESTAMP);
if (time3 != null) stmt.setTimestamp(3, time3); else stmt.setNull(3, java.sql.Types.TIMESTAMP);
if (time4 != null) stmt.setTimestamp(4, time4); else stmt.setNull(4, java.sql.Types.TIMESTAMP);
stmt.executeUpdate();
匹配。以下是我的LEX和YACC文件的顺序相同:
Lex档案:
a^nb^n
YACC档案:
%{
#include <stdio.h>
#include <y.tab.h>
%}
%%
a {return A;}
b {return B;}
. {return yytext[0];}
\n {return NL;}
%%
int yywrap(void) {
return 1;
}
问题在于输出:
输入字符串:aabb
输出:已接受
输入字符串:aabb
输出:拒绝
当第二次输入相同的输入或任何假设接受的输入时,将拒绝接听。我了解到YACC在解析字符串时使用的堆栈。但我找不到任何有关这方面的文件。请帮忙。
答案 0 :(得分:4)
T
规则T : T S NL
| /* empty */
;
是非递归的,这意味着它只匹配一个行。以下修改将观察任意数量的行(包括无)。
$ printf 'aabb\naabb\n' | ./a.out
accepted
accepted
导致连续的行被接受。
private void NavigateFromBrowser()
{
using (var wb = new WebBrowser())
{
wb.Width = Width;
wb.Height = Height;
wb.ScrollBarsEnabled = false;
wb.Navigate(_url);
while (wb.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
}
}
答案 1 :(得分:2)
我无法通过重复运行您的解析器来重现您的结果,但我可以通过在同一次运行中为解析器提供多个字符串来重现它。理解差异是至关重要的:yyparse()
的一次执行是一次运行,并且它将尝试解析整个输入,直到词法分析器信号结束为止。 @kdhp的答案解释了为什么你的解析器在同一次运行中不接受多个字符串,并提供了一种获得你想要的结果的方法。
另一种方法是真正执行多次运行,您可以通过调整解析器和词法分析器来执行。词法分析器在看到换行符时需要报告输入结束,然后解析器根本不需要考虑换行符。
此外,在任何一种情况下所需的词法分析器都非常简单,因此使用lex
(或flex
)生成它是过度的;直接编写合适的yylex()
要简单得多。此外,通过自己编写,您可以更方便地在行尾和输入结束之间区分main()
。一个词法分析器支持语法文件中出现的所有内容,在main()
之前:
int end_of_input = 0;
int yylex(void) {
int c = getc(); /* no buffering inside the lexer */
if (c < 0) {
end_of_input = 1;
}
return ((c == '\n') ? 0 : c);
}
为简单起见,假设解析器使用文字标记,在这种情况下没有特别的理由不这样做。此外,它所需的唯一规则是非终端S
(现在是起始符号)的原始规则的此变体:
S : 'a' S 'b'
| 'a' 'b'
;
使用该词法分析器和该规则,yyparse()
的每次运行将解析最多一行(但可能在行尾之前停止解析错误),并且如果和,则返回0
只有整行成功解析。然后在循环中运行它:
int main(void)
{
do {
if (yyparse() == 0)) {
puts("accepted");
} // else yyerror() already printed "rejected"
} while (!end_of_input);
}
作为最后一点,请注意,如果在输入行的中间某处存在解析错误,则上述内容不会占用该行的其余部分(并且您的版本也不会消耗)。如果在出错之后,您希望继续在main()
中的下一行或通过解析器中的错误规则进行解析。那当然可以做到;我把它留作练习。