AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题

问题[parsing](coding)

Martin Hope
Betty Crokker
Asked: 2025-02-25 04:04:17 +0800 CST

解析 TrueType 字体时出现问题

  • 5

我需要解析一个 TrueType 字体文件来提取某些信息,而且一切顺利,我能够解析很多文件的许多表格类型,只是它在处理一个特定文件的字形数据表(“glyf”)时遇到了麻烦。

我正在解析 indexToLoc 表,因此我知道字形在表中的位置,当我查看该特定字形的数据时,我看到了这个(带有我的注释的十六进制值):

00 02 numContours
FF D1 Xmin=-47
00 00 YMin=0
04 5D XMax=1117
05 87 YMax=1415
00 08 endPoint=8 so the first contour has 9 points [0, 8]
00 16 endPoint=0x16 so the second contour has 14 points [9, 22]

00 2F instructionLength=47

instructions:
40 2C 04 01 00 04 01 4A 05 01 00 00 02 01 00 02 
61 00 04 04 63 4B 03 01 01 01 64 01 4C 00 00 16
15 14 12 0F 0E 0A 09 00 08 00 08 06 0A 14 2B

Reading flags for first contour (has 9 points)
01 Flag[0] = OnCurve
03 Flag[1] = OnCurve, XShort
2E Flag[2] = XShort, YShort, Repeat, YSameOrPositive
01    Repeat count = 1 so Flag[3]=XShort, YShort, (Repeat), YSameOrPositive
27 Flag[4] = OnCurve, XShort, YShort, YSameOrPositive
0E Flag[5] = XShort, YShort, Repeat
01    Repeat count = 1 so Flag[6] = XShort, YShort, (Repeat)
07 Flag[7] = OnCurve, XShort, YShort
09 Flag[8] = OnCurve, Repeat
01    Repeat count = 1 so Flag[9] = OnCurve, (Repeat)

23 22 26 27 03 21 03 0E 01 2B 01 01 33 03 78 AF 04 08 04 0A 13 08 FE A0 03 29 4D 0E 10 03 65 FD 86 CB 05 16 0D 4C 02 C2 63 02 01 02 D0 12 2B 19 19 2B 13 FD 31 FD FF 0F 0B 01 9E FE 62 0B 0F 05 87 00 00

如您所见,第一个轮廓有 9 个点,因此我预计有 9 个标志值,但第 9 个标志设置了“重复”标志,因此我最终得到 10 个标志值。

当“重复”标志位于最后一个标志上时,我是否应该忽略它?还是我在解析这些字节时做了其他错误的事情?

parsing
  • 1 个回答
  • 18 Views
Martin Hope
hdz1412
Asked: 2025-01-09 23:56:54 +0800 CST

如何在 ANTLR 语法中将返回语句限制为函数声明?

  • 5

问题:我正在使用 ANTLR 开发自定义解析器来定义一种小型编程语言。其中一个要求是返回语句只能出现在函数主体内。如果返回语句出现在函数外部,解析器应该抛出错误。

以下是我正在使用的简化语法(在 ANTLR 中):

grammar Grammar;

options {
    language=Python3;
}

// Parser Rules
program: (var_decl | fun_decl)*;

fun_decl: type_spec ID '(' param_decl* (';' param_decl)* ')' body; // Function declarations
param_decl: type_spec ID (',' ID)* ; // Parameters for functions
type_spec: 'int' | 'float' ; // Valid types

body: '{' stmt* '}'; 
expr: 'expr';

stmt: assignment | call | r_return | var_decl;
var_decl: param_decl ';'; // Variable declarations
assignment: ID '=' expr ';';
call: ID '(' expr* (',' expr)* ')' ';';
r_return: 'return' expr ';';

// Lexer Rules
WS: [ \t\r\n] -> skip ; // Skip whitespace
ID: [a-zA-Z]+ ; // Identifiers (variable and function names)
ERROR_CHAR: . {raise ErrorToken(self.text)} ; // Error handling

问题是,此语法允许返回语句 (r_return) 出现在允许 stmt 的任何地方,包括全局范围内。例如:

int x;
return x; // This should throw an error.

但在函数内部,它应该可以工作:

int myFunction() {
    return 42; // Valid
}

我想了想,但没有找到解决办法。请帮帮我。

parsing
  • 2 个回答
  • 26 Views
Martin Hope
David542
Asked: 2025-01-07 06:08:25 +0800 CST

是否有任何语言允许函数名称中有空格?

  • 1

通常,函数标记是普通标识符 ( [A-z_][0-9A-z_]*) 或其某种变体。是否有任何语言支持包含空格的带引号的函数名称?例如:

`my function`(x,y,z)  # using back-tick quoting
parsing
  • 1 个回答
  • 49 Views
Martin Hope
David542
Asked: 2024-12-21 09:12:14 +0800 CST

为什么词法分析器通常将 var 定义为不能以数字开头?

  • 6

标记_123jh和123jh导致大多数词法分析器不包含以数字开头的标识符之间的区别是什么?我猜一个原因可能是纯数字标记可能会造成混淆,因此完全消除前导数字比允许类似以下内容更容易:

^(\d+[A-z_][A-z_0-9]*|[_A-z][A-z0-9]*)$。

或者还有其他原因(也许词法分析器无法保证以这种方式进行单字符前瞻)?

parsing
  • 1 个回答
  • 42 Views
Martin Hope
Yevgeniy P
Asked: 2024-12-19 19:30:03 +0800 CST

如何强制在规则中对非终端符号使用相同的生成式?

  • 6

假设我有一个 ANTLR 语法:

program = word (' ' word)*
  ;

word = 'dog' | 'cat' | 'bird'
  ;

据我了解,它将匹配上述任何单词序列,例如“dog dog cat”、“dog cat bird cat”等。但如果我只想匹配相同值的重复,例如“dog dog”、“cat cat cat cat”、“bird bird bird”等,该如何修改上述语法来做到这一点?

换句话说,我希望“program”规则中重复出现的非终端符号“word”始终匹配相同的生成规则,而不是为“word”指定的任何规则,但不必在“program”规则中明确列出它们中的每一个(例如,如果“word”有大量的替代方案),这意味着我想避免这样的事情:

program:
    'dog' (' ' 'dog')*
  | 'cat' (' ' 'cat')*
  | 'bird' (' ' 'bird')*
  ...
  ;

我认为在正则表达式中,这是使用反向引用(例如“\1”)实现的,在 ANTLR 语法中是否有等效的实现,或者有其他方法可以实现?

parsing
  • 1 个回答
  • 53 Views
Martin Hope
Dendrit
Asked: 2024-12-01 05:10:39 +0800 CST

使用递归下降法解析扩展的 lambda 演算

  • 5

我正在用 C 语言编写基于简单 lambda 演算的解释器。语言的 EBNF 是

S ::= E
E ::= 'fn' var '->' E | T {'+' T} | T {'-' T}
T ::= F {'*' F} | F {'/' F}
F ::= P {P}
P ::= var | number | '(' E ')'

我已经为相同语法编写了解析器,但没有第 4 条生成规则。但我该如何处理{P}?

当然,我可以只检查前瞻标记,如果它是 var、number 或 '(',则调用解析 P 的过程(比如说parse_primitive),但在这种情况下,我将进行相同的额外前瞻检查parse_primitive,所以我肯定做错了什么。

编辑:我的代码现在看起来像这样:

Ast *parse_expr(Lexer *lexer) {
  if (match_token(lexer, TOK_KW_FN) {
    expect_token(lexer, TOK_VAR);
    char *lexeme = get_last_lexeme(lexer);
    Ast *var = make_var(lexeme);
    expect_token(lexer, TOK_ARROW);
    Ast *body = parse_expr(lexer);
    return make_ast(var, body);
  } else {
    Ast *expr = parse_term(lexer);
    for (;;) {
      int op;
      if (match_token(lexer, TOK_PLUS)) {
        op = OP_ADD;
      } else if (match_token(lexer, TOK_MINUS)) {
        op = OP_SUB;
      } else {
        return expr;
      }
      Ast *term = parse_term(lexer);
      expr = make_binop(op, expr, term);
    }
  }
}

Ast *parse_term(Lexer *lexer) {
  Ast *term = parse_factor(lexer);
  for (;;) {
    int op;
    if (match_token(lexer, TOK_STAR)) {
      op = OP_MUL;
    } else if (match_token(lexer, TOK_SLASH)) {
      op = OP_DIV;
    } else {
      return term;
    }
    Ast *factor = parse_factor(lexer);
    term = make_binop(op, term, factor);
  }
}

Ast *parse_factor(Lexer *lexer) {
  Ast *factor = parse_primitive(lexer);
  for (;;) {
    int tok = lexer_peek(lexer);
    if (tok != TOK_LPAR && tok != TOK_VAR && tok != TOK_NUMBER) { /* i want to remove this check as if is actually done by parse_primitive */
      return factor;
    }
    Ast *primitive= parse_primitive(lexer);
    factor = make_app(factor, primitive);
  }
}

Ast *parse_primitive(Lexer *lexer) {
  if (lexer_match(lexer, TOK_LPAR)) {
    Ast *expr = parse_expr(lexer);
    if (!lexer_match(lexer, TOK_RPAR)) {
      parser_error("expected ')'");
    }
    return expr;
  } else if (lexer_match(lexer, TOK_NUMBER)) {
    char *lexeme = get_last_lexeme(lexer);
    return make_number(lexeme);
  } else if (lexer_match(lexer, TOK_VAR)) {
    char *lexeme = get_last_lexeme(lexer);
    return make_var(lexeme);
  }
  parser_error("expected '(', number or var");
}
parsing
  • 1 个回答
  • 50 Views
Martin Hope
Zzen
Asked: 2024-11-18 12:42:00 +0800 CST

如何使用结构在 Racket 语言解释器中实现三元条件?

  • 5

我正在开发 Racket 中一种简单语言的解释器,我需要实现类似于 JavaScript 的三元条件 (Expr ? Expr : Expr)。我的语言支持加法、减法和相等等基本运算,现在我要添加布尔值和这个三元运算。

这是我当前的解析代码;;解析:Expr -> AST;;将“自定义语言”Expr 解析为 AST

(define (parse expr)
  (match expr
    [(? number?) (num expr)]                      
    [(? string?) (str expr)]                      
    ['TRUE (bool #t)]                            
    ['FALSE (bool #f)]                           
    [`(+ ,x ,y) (add (parse x) (parse y))]        
    [`(- ,x ,y) (sub (parse x) (parse y))]       
    [`(=== ,x ,y) (equals (parse x) (parse y))]  
    [`(,test '? ,true ': ,false)                 
     (condt (parse test) (parse true) (parse false))]
    [_ (error "Invalid custom Lang expression")]))

我现在正在学习 racket,而且我以前只有 java 经验。我假设这就像 java 中的类,并且我定义可以解析什么?然后我会有一个运行 fn,它接受解析的输入和输出结果。

这是我的跑步

;; run: AST -> Result
;; Computes the result of running a customLang AST
(define (run ast)
  (match ast
    [(num n) n]
    [(str s) s]
    [(bool b) b]
    [(add x y) (cus+ (run x) (run y))]
    [(sub x y) (cus- (run x) (run y))]
    [(equals x y) (equal? (run x) (run y))]
    [(condt test true-branch false-branch)
     (if (truthy? (run test)) (run true-branch) (run false-branch))]
    [_ NaN]))

所以我理解这是如果 true 则先运行,如果 false 则再运行。而且我的解析似乎设置正确。但是当我尝试运行测试时

   ;; JS "truthy" true
   (check-equal? (evalcustom '(10 ? 100 : 200)) 100)

   ;; JS "truthy" false
   (check-equal? (evalcustom '((- 100 100) ? "a" : "b")) "b")))

它无法识别,只能输出我创建的错误消息。我不知道如何让这个结构和 AST 树一起工作,以及它们为什么应该工作。因此,我不知道如何调试我的问题。

谢谢您的帮助,我非常感激。

parsing
  • 1 个回答
  • 24 Views
Martin Hope
Thermatix
Asked: 2024-09-23 21:40:34 +0800 CST

Rust FromStr 中要解析的类型具有通用字段,并且您在尝试解析之前不会知道类型

  • 5

假设您有一个想要解析的具体类型(您创建/拥有的),但该类型有一个通用字段,在这个例子中,我们会说可能的类型只有u8,u16& u32,并且我们只能说其他任何东西都是不正确的或太大。

假设以下情况:

  • 我已经简化了我实际使用的代码
  • 我不能直接转换为相同的类型,它们必须根据大小为 u8、u16 或 u32(粗略地模拟我实际想要的
  • 我这样展示是因为实际代码引入了太多内容,这是最小代码示例
  • 我已经尝试过对每个类型执行等操作impl FromStr for Test<u8> {},但随后编译器会抱怨(测试需要泛型),然后当我添加时会抱怨实现冲突,impl<T> FromStr for Test<T> {}这是有道理的,因为 rust 还没有专业化
  • 实际代码不使用u8,u16或者u32,我正在尝试使我的示例代码更广泛地适用

我有以下代码:

use std::str::FromStr;

#[derive(Debug)]
struct Test<T = u8> {
    field: T
}

impl<T> FromStr for Test<T> {
    type Err = std::num::ParseIntError;
    
    fn from_str(buff: &str) -> Result<Test<T>, Self::Err> {
        let attempt: Result<u8, Self::Err> = buff.parse();
        if let Ok(field) = attempt { return Ok(Test::<u8> { field }) };
        
        let attempt: Result<u16, Self::Err> = buff.parse();
        if let Ok(field) = attempt { return Ok(Test::<u16> { field }) };
        
        let attempt: Result<u32, Self::Err> = buff.parse();
        
        match attempt {
            Ok(field) => Ok(Test::<u32> { field }),
            Err(err) => Err(err)
        }
    } 
}



fn main() -> Result<(), std::num::ParseIntError> {
    let u_8 = "128";
    let u_16 = "475";
    let u_32 = "70000";
    
    let test_8: Test = u_8.parse()?;
    let test_16: Test = u_16.parse()?;
    let test_32: Test = u_32.parse()?;
    
    println!("t8: {test_8:?}");
    println!("t16: {test_16:?}");
    println!("t32: {test_32:?}");
    
    Ok(())
 
}

我收到大量错误,例如:

= note: expected struct `Test<T>`
               found struct `Test<u16>`

这是有道理的。

我该如何让它工作?

奖励积分

为什么 Rust 要求我这样做Test::<u8>,因为我已经在每一行上方指定了类型,return为什么 Rust 不能直接推断出Tin Test<T>?

是因为Result<Self, Self::Err>和Self吗Test<T>?

parsing
  • 1 个回答
  • 32 Views
Martin Hope
apache
Asked: 2024-09-20 17:25:15 +0800 CST

ANTLR4 - 令牌识别错误和输入不匹配

  • 5

我对 ANTLR 语法还不太熟悉。以下是我的 g4 文件中的内容:

tptp_file               : tptp_input* EOF;
tptp_input              : annotated_formula | include;

annotated_formula : fof_annotated  |  cnf_annotated;
fof_annotated : 'fof('name','formula_role','fof_formula annotations').';

name : atomic_word  |  integer;

atomic_word : lower_word  |  single_quoted;

lower_word : lower_alpha alpha_numeric'*';

lower_alpha : '[a-z]';
upper_alpha : '[A-Z]';
numeric : '[0-9]';

alpha_numeric : '('lower_alpha | upper_alpha | numeric | '[_])';

...

我尝试在这个包含以下内容的测试文件上使用 ANTLR 解析器:

fof(an,axiom,p).

但我收到一条错误消息:

line 1:4 token recognition error at: 'a'
line 1:5 token recognition error at: 'n'
line 1:7 token recognition error at: 'a'
line 1:8 token recognition error at: 'x'
line 1:9 token recognition error at: 'io'
line 1:11 token recognition error at: 'm'
line 1:13 token recognition error at: 'p'
line 1:6 mismatched input ',' expecting {'(', ''', '[1-9]', '[a-z]'}
line 1:12 mismatched input ',' expecting '[a-z]'
line 1:14 mismatched input ').' expecting {'(', '[', '[]', '!', '~', '?', '#', '["]', ''', '[1-9]', '[a-z]', '[A-Z]', '[$]'}

有人能帮我了解我做错了什么以及如何解决吗?谢谢。

我将 lower_alpha 声明为一个片段。

parsing
  • 1 个回答
  • 20 Views
Martin Hope
Chris Geo
Asked: 2024-08-01 05:38:32 +0800 CST

如何找到 LR0 项目的 FOLLOW 集?

  • 5

我正在尝试实现一个 LR1 解析器,使用这篇wikipedia 文章中的帮助。我已经为 LR0 项创建了一个闭包函数,当尝试为 LR1 项创建闭包时(关于向 LR0 项添加前瞻的部分),我需要计算 FIRST 和 FOLLOW 集,但是 wiki 提到了2 个 FOLLOW 集,一个接受 LR0 项,另一个只接受项集和非终结符。第二个很容易理解:

pub fn lr0_follow_in_item_set(
    rules: &[Rule],
    item_set: &[LR0Item],
    nt: &NonTerminal,
) -> BTreeSet<Terminal> {
    let mut res = BTreeSet::new();
    for item in item_set { // 
        if Some(TerminalOrNonTerminal::NonTerminal(*nt)) == item.next_symbol(rules) { // item in item set where dot is before the desired non terminal
            res.extend(lr0_follow(rules, item)); // union of the follow sets
        }
    }
    res
}

但是我找不到 LR0 项 ( lr0_follow(rules, item)) 的 FOLLOW 实现,它是否与 FOLLOW(nonterminal) 相同,其中 nonterminal 是项点后的非终端(如果有,否则返回空集)?

注意:我的 LR1 解析器不使用 epsilon。

我不知道该尝试什么,因为我找不到此特定 FOLLOW 集的任何资源。

parsing
  • 1 个回答
  • 28 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    重新格式化数字,在固定位置插入分隔符

    • 6 个回答
  • Marko Smith

    为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会?

    • 2 个回答
  • Marko Smith

    VScode 自动卸载扩展的问题(Material 主题)

    • 2 个回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Martin Hope
    Fantastic Mr Fox msvc std::vector 实现中仅不接受可复制类型 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant 使用 chrono 查找下一个工作日 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor 构造函数的成员初始化程序可以包含另一个成员的初始化吗? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský 为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul C++20 是否进行了更改,允许从已知绑定数组“type(&)[N]”转换为未知绑定数组“type(&)[]”? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann 为什么 {2,3,10} 和 {x,3,10} (x=2) 的顺序不同? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve