我写一个正在修改输入中所有空格的正则表达式有一个大问题.
我试过了\s+,[ \t\t\r]+但那不起作用.
我需要这个,因为我正在使用flex编写一个扫描仪,我被困在匹配的空格中.空格应该匹配而不是删除.
输入示例:
program
3.3 5 7
{ comment }
string
panic: cant happen
Run Code Online (Sandbox Code Playgroud) 如果这是一个愚蠢的问题我很抱歉,但我对这个工具有0次经验,想知道我是否正在使用它.我已经下载了flex,在编译我的lex文件时,会生成一个C文件,然后需要单独编译.这是最好的方法吗?
我目前正在尝试使用Flex + Bison编写一个小编译器,但我在错误处理方面有点迷失,特别是如何使所有东西都融合在一起.为了激发讨论,请考虑我用于字符串文字的以下词法分析器片段:
["] { BEGIN(STRING_LITERAL); init_string_buffer(); }
<STRING_LITERAL>{
\\\\ { add_char_to_buffer('\\'); }
\\\" { add_char_to_buffer('\"'); }
\\. { /*Invalid escape. How do I treat this error?*/ }
["] { BEGIN(INITIAL); yylval = get_string_buffer(); return TK_STRING; }
}
Run Code Online (Sandbox Code Playgroud)
如何处理无效转义的情况?现在我只是打印一条错误消息并打电话exit但我更愿意继续前进并在可能的情况下检测每个文件多个错误.
我的问题:
是否存在在运行时生成AST /解析树的解析器?有点像接受一串EBNF语法或类似的东西并吐出数据结构的库?
现在我知道解析器组合器.(谢谢,Jonas)和一些图书馆(感谢eliben)
顺便说一下,我最近也注意到了Parsing Expression Grammars,听起来很酷的是有人实现它(他们说Perl 6会有它,但是Perl逃避了我的理解)
请问我面临一个简单的问题..这是问题,在我的lex文件中我有类似的东西:
char *ptr_String;
"name = " { BEGIN sName; }
<sName>.+ {
ptr_String = (char *)calloc(strlen(yytext)+1, sizeof(char));
strcpy(ptr_String, yytext);
yylval.sValue = ptr_String;
return NAME;
}
Run Code Online (Sandbox Code Playgroud)
现在在我的Yacc文件中,我有类似于:
stmt_Name:
NAME
{
/*Now here i need to get the matched string of <sName>.+ and measure it's length. */
/*The aim is simply outputing the name to the screen and storing the length in a global variable.
}
;
Run Code Online (Sandbox Code Playgroud)
请问有什么建议?非常感谢您的所有时间和帮助.
我正在使用ply并注意到存储在t.lex.lexmatch中的令牌重新匹配与使用re模块以通常方式定义的sre_pattern之间存在奇怪的差异.小组(x)似乎是1.
我已经定义了一个简单的词法分析器来说明我所看到的行为:
import ply.lex as lex
tokens = ('CHAR',)
def t_CHAR(t):
r'.'
t.value = t.lexer.lexmatch
return t
l = lex.lex()
Run Code Online (Sandbox Code Playgroud)
(我收到关于t_error的警告但暂时忽略它.)现在我将一些输入提供给词法分析器并获取一个令牌:
l.input('hello')
l.token()
Run Code Online (Sandbox Code Playgroud)
我得到了LexToken(CHAR,<_sre.SRE_Match object at 0x100fb1eb8>,1,0).我想看一下匹配对象:
m = _.value
Run Code Online (Sandbox Code Playgroud)
所以现在我看看这些小组:
m.group()=> 'h'正如我所料.
m.group(0)=> 'h'正如我所料.
m.group(1)=> 'h',但我希望它没有这样一个群体.
将此与手动创建这样的正则表达式进行比较:
import re
p = re.compile(r'.')
m2 = p.match('hello')
Run Code Online (Sandbox Code Playgroud)
这给了不同的群体:
m2.group()= 'h'正如我所料.
m2.group(0)= 'h'正如我所料.
m2.group(1)IndexError: no such group按照我的预期给出.
有谁知道为什么存在这种差异?
我对Lex和Yacc很新.我有一个Lex程序.例:wordcount.l
我正在使用窗户和腻子.
我只是想运行这个文件..
该wordcount.l文件是否在C盘上?
我是否编译Lex程序并生成.c程序然后我运行什么?
我尝试了命令行:Lex wordcount.l
但我只是找不到档案......
wordcount.l
%{
#include <stdlib.h>
#include <stdio.h>
int charCount=0;
int wordCount=0;
int lineCount=0;
%}
%%
\n {charCount++; lineCount++;}
[^ \t\n]+ {wordCount++; charCount+=yyleng;}
. {charCount++;}
%%
main(argc, argv)
int argc;
char** argv;
{
if (argc > 1)
{
FILE *file;
file = fopen(argv[1], "r");
if (!file)
{
fprintf(stderr, "Could not open %s\n", argv[1]);
exit(1);
}
yyin = file;
}
yylex();
printf("%d %d %d\n", charCount, wordCount, lineCount);
}
Run Code Online (Sandbox Code Playgroud)
在putty中如何编译和运行该程序?
我正在尝试使此示例代码正常工作,但我不断收到错误:fatal error: 'y.tab.h' file not found #include "y.tab.h" 。我该怎么办?
%{
#include <stdlib.h>
void yyerror(char *);
#include "y.tab.h"
%}
%% [0-9]+ {
yylval = atoi(yytext);
return INTEGER;
}
[-+\n] return *yytext;
[ \t] ; /* skip whitespace */
. yyerror("invalid character");
%%
int yywrap(void) {
return 1;
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个lex模式,这将允许我识别IPV6地址,包括带有CIDR表示法的IPV6地址.我使用的模式如下所示.
IPV4ADDRESS_CIDR [ \t]*(((2(5[0-5]|[0-4][0-9])|[01]?[0-9][0-9]?)\.){3}(2(5[0-5]|[0-4][0-9])|[01]?[0-9][0-9]?)(\/(3[012]|[12]?[0-9])))[ \t]*
IPV4ADDRESS [ \t]*(([[:digit:]]{1,3}"."){3}([[:digit:]]{1,3}))[ \t]*
hex4 ([[:xdigit:]]{1,4})
hexseq ({hex4}(:{hex4})*)
hexpart ({hexseq}|({hexseq}::({hexseq}?))|::{hexseq})
IPV6ADDRESS [ \t]*({hexpart}(":"{IPV4ADDRESS})?)[ \t]*
IPV6ADDRESS_CIDR [ \t]*(IPV6ADDRESS)(\/(1[01][0-9]|12[0-8]|[0-9]{1,2}))[ \t]*
Run Code Online (Sandbox Code Playgroud)
IPV6ADDRESS_CIDR的正则表达式没有按预期工作.我正在测试
2001:1234::5678:5:6:7:8/64
Run Code Online (Sandbox Code Playgroud)
它似乎没有正确识别它.我在这里犯了一些错误?
莱克斯部分:
%%
[0-9]+ { yyval = atoi (yytext); return num; }
%%
Run Code Online (Sandbox Code Playgroud)
Yacc 部分:
%token num
%%
exp:num '+' num ; {$$ = $1 + $3;}
%%
Run Code Online (Sandbox Code Playgroud)
$$,$1和$2代表什么?$$?5+9作为输入发送到该程序5并被9lex 程序识别,但是 呢+?符号+是否发送到 lex?lex ×10
flex-lexer ×3
regex ×3
yacc ×3
bison ×2
c ×2
cidr ×1
interpreter ×1
ip-address ×1
ipv6 ×1
lexer ×1
parsing ×1
ply ×1
python ×1
windows ×1