gpt4 book ai didi

antlr - 我如何对这个输入进行词法分析?

转载 作者:行者123 更新时间:2023-12-02 00:40:19 25 4
gpt4 key购买 nike

我目前有一种使用 ANTLR 在 Java 中实现的有效、简单的语言。我想要做的是以类似于 PHP 的方式将其嵌入到纯文本中。

例如:

Lorem ipsum dolor sit amet
<% print('consectetur adipiscing elit'); %>
Phasellus volutpat dignissim sapien.

我预计生成的 token 流类似于:

CDATA OPEN PRINT OPAREN APOS STRING APOS CPAREN SEMI CLOSE CDATA

我怎样才能做到这一点,或者有更好的方法吗?

对于 <% 之外的内容没有限制堵塞。我假设类似 <% print('%>'); %> ,根据 Michael Mrozek 的回答,这是可能的,但在这种情况之外,<%将始终指示代码块的开始。


示例实现

我根据 Michael Mrozek 的回答中给出的想法开发了一个解决方案,使用 ANTLR 的门控语义谓词模拟 Flex 的开始条件:

lexer grammar Lexer;

@members {
boolean codeMode = false;
}

OPEN : {!codeMode}?=> '<%' { codeMode = true; } ;
CLOSE : {codeMode}?=> '%>' { codeMode = false;} ;
LPAREN : {codeMode}?=> '(';
//etc.

CHAR : {!codeMode}?=> ~('<%');


parser grammar Parser;

options {
tokenVocab = Lexer;
output = AST;
}

tokens {
VERBATIM;
}

program :
(code | verbatim)+
;

code :
OPEN statement+ CLOSE -> statement+
;

verbatim :
CHAR -> ^(VERBATIM CHAR)
;

最佳答案

but outside of a situation like that, <% would always indicate the start of a code block.

在这种情况下,首先扫描文件以查找您的嵌入式代码,一旦获得这些代码,就使用专用解析器解析您的嵌入式代码(在 <%%> 标记之后没有噪音)。

ANTLR 可以选择让词法分析器只解析输入文件的(小)部分而忽略其余部分。请注意,在这种情况下,您不能创建“组合语法”(解析器和词法分析器合二为一)。以下是创建此类“部分词法分析器”的方法:

// file EmbeddedCodeLexer.g
lexer grammar EmbeddedCodeLexer;

options{filter=true;} // <- enables the partial lexing!

EmbeddedCode
: '<%' // match an open tag
( String // ( match a string literal
| ~('%' | '\'') // OR match any char except `%` and `'`
| {input.LT(2) != '>'}?=> '%' // OR only match a `%` if `>` is not ahead of it
)* // ) <- zero or more times
'%>' // match a close tag
;

fragment
String
: '\'' ('\\' . | ~('\'' | '\\'))* '\''
;

如果您现在从中创建词法分析器:

java -cp antlr-3.2.jar org.antlr.Tool EmbeddedCodeLexer.g 

并创建一个小测试工具:

import org.antlr.runtime.*;

public class Main {
public static void main(String[] args) throws Exception {
String source = "Lorem ipsum dolor sit amet \n"+
"<% \n"+
"a = 2 > 1 && 10 % 3; \n"+
"print('consectetur %> adipiscing elit'); \n"+
"%> \n"+
"Phasellus volutpat dignissim sapien. \n"+
"foo <% more code! %> bar \n";
ANTLRStringStream in = new ANTLRStringStream(source);
EmbeddedCodeLexer lexer = new EmbeddedCodeLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
for(Object o : tokens.getTokens()) {
System.out.println("=======================================\n"+
"EmbeddedCode = "+((Token)o).getText());
}
}
}

全部编译:

javac -cp antlr-3.2.jar *.java

最后运行 Main 类:

// *nix/MacOS
java -cp .:antlr-3.2.jar Main

// Windows
java -cp .;antlr-3.2.jar Main

它将产生以下输出:

=======================================
EmbeddedCode = <%
a = 2 > 1 && 10 % 3;
print('consectetur %> adipiscing elit');
%>
=======================================
EmbeddedCode = <% more code! %>

关于antlr - 我如何对这个输入进行词法分析?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2798545/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com