Questions tagged «grammar»

形式语法是一组生产规则,描述了如何形成有效语法的字符串。形式语法最常用于指定编程语言的语法。

20
C ++是上下文无关的还是上下文相关的?
我经常听到有人声称C ++是上下文相关的语言。请看以下示例: a b(c); 这是变量定义还是函数声明?这取决于符号的含义c。如果c是变量,则a b(c);定义一个名为btype 的变量a。直接用初始化c。但如果c是类型,则a b(c);声明一个名为的函数b,该函数采用a c并返回a a。 如果您查看无上下文语言的定义,它将基本上告诉您所有语法规则的左手边必须仅由一个非终结符组成。另一方面,上下文相关的语法允许在左侧使用任意字符串的终止符和非终止符。 浏览“ C ++编程语言”的附录A,我找不到一个单独的语法规则,该规则除左侧有一个非终结符外还没有其他内容。这意味着C ++是无上下文的。(当然,每种上下文无关的语言也是上下文敏感的,因为上下文无关的语言构成了上下文敏感语言的子集,但这并不是重点。) 那么,C ++是上下文无关的还是上下文相关的?

20
int a [] = {1,2,}; 允许使用怪异的逗号。有什么特殊原因吗?
也许我不是来自这个星球,但是在我看来,以下内容应该是语法错误: int a[] = {1,2,}; //extra comma in the end 但事实并非如此。当在Visual Studio中编译的代码我很惊讶,但我已经学会了不信任MSVC编译器尽可能C ++的规则而言,所以我检查的标准,它是标准允许为好。如果您不相信我,可以查看8.5.1的语法规则。 为什么允许这样做?这可能是一个愚蠢的无用问题,但我想让您理解我为什么要问。如果这是一般语法规则的子情况,我会理解-他们决定不为了简化通用语法而仅仅在初始化器列表的末尾不允许多余的逗号。但是不可以,其他逗号是明确允许的。例如,不允许在函数调用参数列表的末尾(当函数采用时...)使用多余的逗号,这是正常现象。 那么,是否再次有明确的理由允许这个多余的逗号呢?

6
为什么不能用LR(1)解析器解析C ++?
我正在阅读有关解析器和解析器生成器的信息,并在Wikipedia的LR解析页面中找到以下语句: 可以使用LR解析器的某些变体来解析许多编程语言。C ++是一个值得注意的例外。 为什么会这样呢?C ++的哪些特殊属性导致无法使用LR解析器进行解析? 使用谷歌,我只发现C可以用LR(1)完美解析,但是C ++需要LR(∞)。

2
什么是上下文无关语法?
有人可以向我解释什么是上下文无关的语法吗?在查看了Wikipedia条目,然后查看了有关正式语法的Wikipedia条目之后,我完全被迷住了。有人会乐于解释这些东西吗? 我想知道这一点是因为我希望研究解析以及正则表达式引擎的局限性。 我不确定这些术语是否与编程直接相关,或者它们是否与语言学总体上更相关。抱歉,如果这样的话,也许可以动议吗?

8
LR,SLR和LALR解析器之间有什么区别?
LR,SLR和LALR解析器之间的实际区别是什么?我知道SLR和LALR是LR解析器的类型,但是就它们的解析表而言,实际区别是什么? 以及如何显示语法是LR,SLR还是LALR?对于LL语法,我们只需要显示解析表的任何单元格都不应包含多个生产规则。LALR,SLR和LR是否有类似规则? 例如,如何显示语法 S --> Aa | bAc | dc | bda A --> d 是LALR(1)但不是SLR(1)? 编辑(ybungalobill):对于LALR和LR之间的区别,我没有得到满意的答案。因此,LALR的表较小,但只能识别LR语法的一个子集。有人可以详细说明一下LALR和LR之间的区别吗?LALR(1)和LR(1)就足够回答了。他们都使用1个令牌前瞻和双方都表驱动!它们有何不同?

1
是什么使Java比C更容易解析?
我熟悉C和C ++的语法对上下文敏感的事实,特别是您需要在C中使用“ lexer hack”。另一方面,我的印象是您可以仅用尽管这两种语言之间有相当大的相似性,但它们还是2个前瞻标记。 为了使C解析起来更容易处理,您需要更改什么? 我之所以问是因为,我所见过的有关C的上下文敏感度的所有示例在技术上都是允许的,但非常奇怪。例如, foo (a); 可能正在foo通过参数调用void函数a。或者,它可能声明a是type的对象foo,但您也可以轻松摆脱寄生。在某种程度上,这种怪异之所以会发生是因为C语法的“直接声明符”生成规则满足了声明函数和变量的双重目的。 另一方面,Java语法对变量声明和函数声明有单独的生产规则。如果你写 foo a; 那么您知道它是一个变量声明,foo可以明确地解析为类型名。如果foo尚未在当前作用域的某个位置定义该类,则这可能不是有效的代码,但这是语义分析的工作,可以在以后的编译器遍历中执行。 我已经看到它说由于typedef很难解析C,但是您也可以在Java中声明自己的类型。除了direct_declarator,还有哪些C语法规则有误?
90 java  c  parsing  grammar 

1
为什么019不是JavaScript语法错误?还是为什么019> 020
如果我输入019 > 020JavaScript控制台(在Chrome和Firefox中都经过测试),则会得到答案true。 这是由于020被解释为OctalIntegerLiteral(等于16),而019显然是被解释为DecimalLiteral(等于19)。如19大于16,019 > 020则为true。 让我感到困惑的是为什么019将其解释为DecimalLiteral第一位。这是什么产品?DecimalIntegerLiteral不允许019: DecimalIntegerLiteral :: 0 NonZeroDigit DecimalDigits_opt OctalIntegerLiteral也不允许019(因为9不是八进制数字): OctalIntegerLiteral :: 0 OctalDigit OctalIntegerLiteral OctalDigit OctalDigit :: one of 0 1 2 3 4 5 6 7 因此,从我在规范中看到的内容来看,019实际上应该拒绝它,我不明白为什么将其解释为十进制整数。 我猜这里有某种兼容规则,但是我没有找到正式的定义。可以请任何人帮助我吗? (为什么需要这样做:我正在使用JavaCC开发Java的JavaScript / ECMAScript解析器,因此必须特别注意其规范-及其偏差。)

1
LL和递归下降解析器之间的区别?
我最近正在尝试自学解析器(针对语言/无上下文语法)的工作方式,除了一件事之外,大多数解析器似乎都有意义。我特别关注LL(k)语法,这两个主要算法似乎是LL解析器(使用堆栈/解析表)和递归下降解析器(仅使用递归)。 据我所知,递归下降算法适用于所有LL(k)语法,甚至可能更多,而LL解析器适用于所有LL(k)语法。但是,递归下降解析器显然比LL解析器要简单得多(就像LL解析器比LR解析器一样简单)。 所以我的问题是,使用两种算法时可能遇到的优点/问题是什么?鉴于LL处理相同的语法集并且实现起来比较棘手,为什么人们会选择LL而不是递归血统?


3
如何定义Raku语法来解析TSV文本?
我有一些TSV数据 ID Name Email 1 test test@email.com 321 stan stan@nowhere.net 我想将其解析为哈希列表 @entities[0]<Name> eq "test"; @entities[1]<Email> eq "stan@nowhere.net"; 我在使用换行元字符来分隔标题行和值行时遇到麻烦。我的语法定义: use v6; grammar Parser { token TOP { <headerRow><valueRow>+ } token headerRow { [\s*<header>]+\n } token header { \S+ } token valueRow { [\s*<value>]+\n? } token value { \S+ } } my …
13 csv  grammar  raku 

1
在EOS停止Raku语法(字符串结尾)
在学习一种音乐语言的翻译者(从ABC到Alda)作为学习Raku DSL能力的借口的过程中,我注意到似乎没有一种方法可以终止.parse!这是我缩短的演示代码: #!/home/hsmyers/rakudo741/bin/perl6 use v6d; # use Grammar::Debugger; use Grammar::Tracer; my $test-n01 = q:to/EOS/; a b c d e f g A B C D E F G EOS grammar test { token TOP { <score>+ } token score { <.ws>? [ | <uc> | <lc> ]+ <.ws>? } token …
9 parsing  grammar  raku 

2
如何设置可以处理歧义的语法
我正在尝试创建一种语法来解析我设计的一些类似于Excel的公式,其中字符串开头的特殊字符表示其他来源。例如,$可以表示一个字符串,因此“ $This is text”将被视为程序中的字符串输入,并且&可以表示一个函数,因此&foo()可以被视为对内部函数的调用foo。 我面临的问题是如何正确构建语法。例如,这是MWE的简化版本: grammar = r'''start: instruction ?instruction: simple | func STARTSYMBOL: "!"|"#"|"$"|"&"|"~" SINGLESTR: (LETTER+|DIGIT+|"_"|" ")* simple: STARTSYMBOL [SINGLESTR] (WORDSEP SINGLESTR)* ARGSEP: ",," // argument separator WORDSEP: "," // word separator CONDSEP: ";;" // condition separator STAR: "*" func: STARTSYMBOL SINGLESTR "(" [simple|func] (ARGSEP simple|func)* ")" %import common.LETTER …
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.