我有兴趣通过实现基于堆栈的编程语言来扩展我对计算机编程的了解.我正在寻找关于从哪里开始的建议,因为我打算让它具有像" pushint 1"这样的函数,它可以将值为1的整数推送到堆栈的顶部,并通过像" L01: jump L01:" 这样的标签来控制流量.
到目前为止,我已经实现了我希望我的语言行为的C#实现(想要链接到它但IDEOne被阻止),但它非常混乱,需要优化.它将输入转换为XML,然后解析它.我的目标是使用较低级别的语言(可能是C/C++),但我的问题是实现一个可以容纳各种数据类型并且没有固定大小的堆栈.
最后我还想实现数组和函数.另外,我认为我需要有一个更好的Lexer,我想知道解析树是否适合这种简单的语言.
任何建议/批评都是受欢迎的,请考虑我仍然是编程的新手(我刚刚完成了AP CompSci I).此外,欢迎链接到基于开源堆栈的语言.
这是一个基本的程序,我想尝试解释/编译(在哪里[this is a comment]):
[Hello World!]
pushchar '\n'
pushstring "Hello World!"
print
[Count to 5 and then count down!]
pushint 1
setlocal 0
L01:
pushchar '\n'
getlocal 0
print [print x + '\n']
getlocal 0
increment
setlocal 0 [x = x + 1]
pushint 5
getlocal 0
lessthan [x < 5]
iftrue L01
L02:
pushchar '\n'
getlocal 0
print [print x + '\n']
getlocal …Run Code Online (Sandbox Code Playgroud) 对于C或C++,哪种词法分析器/解析器生成器是最好的(最容易使用,最快)?我现在正在使用flex和bison,但是bison只处理LALR(1)语法.我解析语言并不真的需要无限的前瞻,但无限的先行将使解析了很多更加容易.我应该试试Antlr吗?可可/ R?Elkhound?别的什么?
标题是这样的问题:词汇"lexer"和"parser"是同义词,还是它们不同?维基百科似乎可以互换地使用这些词,但英语不是我的母语,所以我不能确定.
我正在为一个长期过时的文本编辑器的脚本语言实现一个解释器,而我在让词法分析器正常工作方面遇到了一些麻烦.
以下是该语言有问题部分的示例:
T
L /LOCATE ME/
C /LOCATE ME/CHANGED ME/ * *
C ;CHANGED ME;CHANGED ME AGAIN; 1 *
Run Code Online (Sandbox Code Playgroud)
该/人物似乎引用字符串,也充当分隔符C(CHANGE在)命令sed型语法,但它允许任何字符作为分隔符.
我可能实现了大约一半最常见的命令,parse_tokens(line.split())直到现在才使用.这很快又很脏,但效果出奇的好.
为了避免写我自己的词法分析器,我试过了shlex.
除了CHANGE案例之外,它的效果非常好:
import shlex
def shlex_test(cmd_str):
lex = shlex.shlex(cmd_str)
lex.quotes = '/'
return list(lex)
print(shlex_test('L /spaced string/'))
# OK! gives: ['L', '/spaced string/']
print(shlex_test('C /spaced string/another string/ * *'))
# gives : ['C', '/spaced string/', 'another', 'string/', '*', '*']
# desired : any format that …Run Code Online (Sandbox Code Playgroud) 我想用空格缩进创建一个非常简单的语法.每行由1个或多个单词组成,但缩进如python(4个空格或制表符是一个缩进),并且没有缩进的缩写,例如:
if something cool occurs
do this
else
otherwise do this
loop around something
each time doing this
and do that
say good byte
Run Code Online (Sandbox Code Playgroud)
而不是读取每一行,计算缩进并手动构建树是否可以在ANTLR语法中完成所有这些?我的目标语言是Java.
我不确定如何为词法分析器标记源代码.现在,我只能想到使用正则表达式将字符串解析为具有给定规则的数组(标识符,符号,如+, - 等).
例如,
begin x:=1;y:=2;
Run Code Online (Sandbox Code Playgroud)
然后我想标记单词,变量(在这种情况下为x,y)和每个符号(:,=,;).
我一直在尝试用java编写一个简单的词法分析器.
File Token.java如下所示:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public enum Token {
TK_MINUS ("-"),
TK_PLUS ("\\+"),
TK_MUL ("\\*"),
TK_DIV ("/"),
TK_NOT ("~"),
TK_AND ("&"),
TK_OR ("\\|"),
TK_LESS ("<"),
TK_LEG ("<="),
TK_GT (">"),
TK_GEQ (">="),
TK_EQ ("=="),
TK_ASSIGN ("="),
TK_OPEN ("\\("),
TK_CLOSE ("\\)"),
TK_SEMI (";"),
TK_COMMA (","),
TK_KEY_DEFINE ("define"),
TK_KEY_AS ("as"),
TK_KEY_IS ("is"),
TK_KEY_IF ("if"),
TK_KEY_THEN ("then"),
TK_KEY_ELSE ("else"),
TK_KEY_ENDIF ("endif"),
OPEN_BRACKET ("\\{"),
CLOSE_BRACKET ("\\}"),
DIFFERENT ("<>"),
STRING ("\"[^\"]+\""),
INTEGER ("\\d"),
IDENTIFIER ("\\w+");
private final Pattern pattern;
Token(String regex) {
pattern …Run Code Online (Sandbox Code Playgroud) 注意:这是一个自我回答的问题,旨在提供有关ANTLR用户最常犯错误之一的参考.
当我测试这个非常简单的语法时:
grammar KeyValues;
keyValueList: keyValue*;
keyValue: key=IDENTIFIER '=' value=INTEGER ';';
IDENTIFIER: [A-Za-z0-9]+;
INTEGER: [0-9]+;
WS: [ \t\r\n]+ -> skip;
Run Code Online (Sandbox Code Playgroud)
通过以下输入:
foo = 42;
Run Code Online (Sandbox Code Playgroud)
我最终得到以下运行时错误:
第1行:第6行不匹配输入'42'期望INTEGER
第1行:8输入不匹配';' 期待'='
为什么不承认ANTLR 42作为INTEGER在这种情况下?
它应该匹配模式[0-9]+就好了.
如果我颠倒了定义的顺序INTEGER并且IDENTIFIER定义它似乎有效,但为什么顺序首先重要?
我正在使用 Alex + Happy 为 Haskell 中的 DSL 制作解析器。我的 DSL 使用掷骰子作为可能表达式的一部分。
有时我有一个我想解析的表达式,如下所示:
[some code...] 3D6 [... rest of the code]
Run Code Online (Sandbox Code Playgroud)
这应该大致翻译为:
TokenInt {... value = 3}, TokenD, TokenInt {... value = 6}
Run Code Online (Sandbox Code Playgroud)
我的 DSL 也使用变量(基本上是字符串),所以我有一个特殊的标记来处理变量名。所以,有了这个令牌:
"D" { \pos str -> TokenD pos }
$alpha [$alpha $digit \_ \']* { \pos str -> TokenName pos str}
$digit+ { \pos str -> TokenInt pos (read str) }
Run Code Online (Sandbox Code Playgroud)
我现在使用解析时得到的结果是:
TokenInt {... value = 3}, TokenName { ... , name …Run Code Online (Sandbox Code Playgroud) 我正在尝试从头开始创建一种简单的编程语言(解释器),但我想知道为什么我应该使用词法分析器。对我来说,创建一个直接解析代码的解析器似乎会更容易。我在忽略什么?