最近,我开始学习ANTLR.我知道lexers/parsers可以用来构建编程语言.
除了DSL或编程语言之外,您是否曾直接或间接使用词法分析器/解析器工具(和知识)来解决实际问题?普通程序员是否有可能在不了解词法分析器或解析器的情况下解决这些问题?
这已经在我脑海中浮现了一段时间.我对递归下降解析器很感兴趣,并且想知道如何实现它.我想要的是一个简单的解析器,它将理解简单的算术,如"5 + 5"或"(5 + 5)*3".
我认为第一步是编写一个'tokenizer',它获取整个输入字符串并将其分解为许多子字符串.这部分我已经完成了(我甚至不得不在这里询问.如果你不想,你不必关注链接,因为我也在这里发布了相关代码.)使用这个标记器我的,我结束了一个vector的stringS,或令牌.现在,困难的部分:我想解析那些令牌.
我已经阅读了关于递归下降解析器的维基百科文章.我确实理解整体概念,但一如既往,实施有点令人困惑.在那篇文章中,有一个非常简单的编程语言的递归下降解析器的C实现,也在本文中讨论过.我尽可能地研究了这段代码,并尝试基本上写同样的东西,但对于我的程序.以下是该代码.
我真正困惑的是这个解析器的作用.它似乎通过该程序并"期望"语法的某些部分.但一旦到达那里,它会做什么?例如,以下是维基百科代码中应该解析"术语"的一个函数:
void term(void) {
factor();
while (sym == times || sym == slash) {
getsym();
factor();
}
}
Run Code Online (Sandbox Code Playgroud)
这是为了解析这个语法:
term = factor {("*"|"/") factor} .
Run Code Online (Sandbox Code Playgroud)
这是有道理的.但它与实际用语有什么关系呢?假设这个术语只是"6",或者是"3*2"并且有价值6.如何将其纳入其余的输入?不应该term()返回一个double而不是void(返回6)?或者是以其他方式完成的?
另外,将这样的解析器输出到输出代码并立即对输入进行操作(即编译器与解释器)之间的区别是什么?这两个(至少在这个例子中)理论上是以相同的方式实现的,还是它们根本不同?
欢迎任何输入.这是我到目前为止的代码:
#include <iostream>
#include <string>
#include <vector>
#include <ctype.h>
#include <sstream>
using namespace std;
vector<string> symbolize(string);
bool accept(string);
void getSymbol();
void error(string s);
bool expect(string);
void expression();
void term();
void …Run Code Online (Sandbox Code Playgroud) 我使用标签(/ t)作为分隔符,我知道我的数据中有一些空字段,例如:
one->two->->three
Run Code Online (Sandbox Code Playgroud)
其中 - >等于标签.如您所见,空白字段仍被选项卡正确包围.使用循环收集数据:
while ((strLine = br.readLine()) != null) {
StringTokenizer st = new StringTokenizer(strLine, "\t");
String test = st.nextToken();
...
}
Run Code Online (Sandbox Code Playgroud)
然而,Java忽略了这个"空字符串"并跳过了这个领域.
有没有办法绕过这种行为并迫使java在空字段中读取?
我有一个像这样的字符串:
a;b;c;d;e
f;g;h;i;j
1;2;3;4;5
Run Code Online (Sandbox Code Playgroud)
我想逐个元素地解析它.我使用嵌套的strtok函数,但它只是拆分第一行并使令牌指针为null.我怎么能克服这个?这是代码:
token = strtok(str, "\n");
while(token != NULL && *token != EOF)
{
char a[128], b[128];
strcpy(a,token);
strcpy(b,a);
printf("a:%s\n",a);
char *token2 = strtok(a,";");
while(token2 != NULL)
{
printf("token2 %s\n",token2);
token2 = strtok(NULL,";");
}
strcpy(token,b);
token = strtok(NULL, "\n");
if(token == NULL)
{
printf("its null");
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
token 2 a
token 2 b
token 2 c
token 2 d
token 2 e
Run Code Online (Sandbox Code Playgroud) 我有一个方法,它接受一个String参数,并使用NLTK将字符串分解为句子,然后分成单词.然后,它将每个单词转换为小写,最后创建每个单词频率的字典.
import nltk
from collections import Counter
def freq(string):
f = Counter()
sentence_list = nltk.tokenize.sent_tokenize(string)
for sentence in sentence_list:
words = nltk.word_tokenize(sentence)
words = [word.lower() for word in words]
for word in words:
f[word] += 1
return f
Run Code Online (Sandbox Code Playgroud)
我应该进一步优化上面的代码,以加快预处理时间,并且不确定如何这样做.返回值显然应该与上面的完全相同,所以我希望使用nltk虽然没有明确要求这样做.
有什么方法可以加快上面的代码?谢谢.
我做了一个程序,在python中将中缀转换为postfix.问题是当我介绍这些论点时.如果我介绍这样的东西:(这将是一个字符串)
( ( 73 + ( ( 34 - 72 ) / ( 33 - 3 ) ) ) + ( 56 + ( 95 - 28 ) ) )
Run Code Online (Sandbox Code Playgroud)
它将使用.split()拆分它,程序将正常工作.但我希望用户能够介绍这样的东西:
((73 + ( (34- 72 ) / ( 33 -3) )) + (56 +(95 - 28) ) )
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我希望空格可以是微不足道的,但是程序继续用括号,整数(不是数字)和操作数来分割字符串.
我尝试解决它for但我不知道如何捕获整数(73,34,72)而不是一位数(7,3,3,4,7,2)
总而言之,我想要的是将一个字符串((81 * 6) /42+ (3-1)) 分成:
[(, (, 81, *, 6, ), /, 42, +, (, 3, -, 1, ), )]
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用预训练的 BERT 模型进行文本分类。我在我的数据集上训练了模型,并在测试阶段;我知道 BERT 只能接受 512 个标记,因此我编写了 if 条件来检查数据帧中测试语句的长度。如果它比 512 长,我将句子分成序列,每个序列有 512 个标记。然后进行分词器编码。序列的长度是 512,但是,在进行 tokenize 编码后,长度变为 707,并且出现此错误。
The size of tensor a (707) must match the size of tensor b (512) at non-singleton dimension 1
Run Code Online (Sandbox Code Playgroud)
这是我用来执行前面步骤的代码:
tokenizer = BertTokenizer.from_pretrained('bert-base-cased', do_lower_case=False)
import math
pred=[]
if (len(test_sentence_in_df.split())>512):
n=math.ceil(len(test_sentence_in_df.split())/512)
for i in range(n):
if (i==(n-1)):
print(i)
test_sentence=' '.join(test_sentence_in_df.split()[i*512::])
else:
print("i in else",str(i))
test_sentence=' '.join(test_sentence_in_df.split()[i*512:(i+1)*512])
#print(len(test_sentence.split())) ##here's the length is 512
tokenized_sentence = tokenizer.encode(test_sentence)
input_ids = torch.tensor([tokenized_sentence]).cuda()
print(len(tokenized_sentence)) #### here's the length is 707 …Run Code Online (Sandbox Code Playgroud) 我正在尝试将字符串标记为ngrams.奇怪的是,在NGramTokenizer的文档中,我没有看到一个方法会返回被标记化的单个ngrams.实际上我只在NGramTokenizer类中看到两个返回String Objects的方法.
这是我的代码:
Reader reader = new StringReader("This is a test string");
NGramTokenizer gramTokenizer = new NGramTokenizer(reader, 1, 3);
Run Code Online (Sandbox Code Playgroud)
我希望我的输出如下:这,是,a,测试,字符串,这是,是一个测试,测试字符串,这是一个测试,一个测试字符串.
我有一个UITextView,并使用其tokenizer来检查用户点击的单词.
我的目标是改变tokenizer所认为的单词.目前似乎将单词定义为连续的字母数字字符,我希望将单词定义为不是空格字符("")的连续字符.
例如:'foo-bar','foo/bar'和'foo @@ bar'目前都将被视为两个单独的单词('foo'和'bar'),但我希望它们都被视为单个单词单词(因为它们都不包含空格).
该文档讨论了UITextInputStringTokenizer类的子类化,但我找不到某个人这样做的例子,我无法弄清楚如何实现所需的方法:
func isPosition(position: UITextPosition, atBoundary granularity: UITextGranularity, inDirection direction: UITextDirection) -> Bool
func isPosition(position: UITextPosition, withinTextUnit granularity: UITextGranularity, inDirection direction: UITextDirection) -> Bool
func positionFromPosition(position: UITextPosition, toBoundary granularity: UITextGranularity, inDirection direction: UITextDirection) -> UITextPosition?
func rangeEnclosingPosition(position: UITextPosition, withGranularity granularity: UITextGranularity, inDirection direction: UITextDirection) -> UITextRange?
Run Code Online (Sandbox Code Playgroud) 我想将一个字符串拆分成标记.
我撕掉了另一个Stack Overflow问题 - 相当于带有多个字符分隔符的StringTokenizer,但我想知道是否只能使用字符串方法(.equals(),. startSith()等).我不想使用RegEx,StringTokenizer类,模式,匹配器或其他任何东西String.
例如,这就是我想要调用方法的方式
String[] delimiters = {" ", "==", "=", "+", "+=", "++", "-", "-=", "--", "/", "/=", "*", "*=", "(", ")", ";", "/**", "*/", "\t", "\n"};
String splitString[] = tokenizer(contents, delimiters);
Run Code Online (Sandbox Code Playgroud)
这是我扯掉另一个问题的代码(我不想这样做).
private String[] tokenizer(String string, String[] delimiters) {
// First, create a regular expression that matches the union of the
// delimiters
// Be aware that, in case of delimiters containing others (example &&
// and &),
// the longer may …Run Code Online (Sandbox Code Playgroud)